Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
SQL Table Type parametre gecisi hakkında (Çözüldü)
#1
Selamlar

FDStoredProc1 ile SQL uzerinde Table-Type parametresi olan bir Procedure nasıl parametre gecilir.

IF NOT EXISTS (SELECT 1 FROM sys.types WHERE is_table_type = 1 AND name = 'UDTT_Test')
BEGIN
   CREATE TYPE dbo.UDTT_Test AS TABLE(
       SiraNo INT NULL
   );
END
GO

if exists (select * from sys.objects where type = 'P' AND name = 'UTP_Test')
    drop procedure UTP_Test
go

Create procedure [dbo].[UTP_Test]
 @Liste UDTT_Test READONLY
as
begin
 Select * from @Liste L order by L.SiraNo Desc
end
GO

DECLARE @Liste dbo.UDTT_Test

INSERT INTO @Liste (SiraNo)
VALUES  (1), (2), (3);

EXEC UTP_Test @Liste = @Liste;


unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error,
 FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
 FireDAC.Phys, FireDAC.Phys.MSSQL, FireDAC.Phys.MSSQLDef, FireDAC.VCLUI.Wait, FireDAC.Stan.Param,
 FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
 Data.DB, Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids, FireDAC.Comp.DataSet, FireDAC.Comp.Client;

type
 TForm1 = class(TForm)
   FDConn: TFDConnection;
   FDSP: TFDStoredProc;
   DSSP: TDataSource;
   DBGrid1: TDBGrid;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 LTable: TFDMemTable;
begin
 LTable := TFDMemTable.Create(nil);
 try
   // TVP yapısını Delphi tarafında oluştur
   LTable.FieldDefs.Clear;
   LTable.FieldDefs.Add('SiraNo', ftInteger);
   LTable.CreateDataSet;
   LTable.Open;

   // Test verileri
   LTable.Append;
   LTable.FieldByName('SiraNo').AsInteger := 1;
   LTable.Post;

   LTable.Append;
   LTable.FieldByName('SiraNo').AsInteger := 2;
   LTable.Post;

   // Stored Procedure ayarı
   FDSP.Close;
   FDSP.Unprepare;
   FDSP.StoredProcName := 'dbo.UTP_Test;1';

   // Parametreleri otomatik türetmek yerine elle tanımla
   FDSP.FetchOptions.Items := FDSP.FetchOptions.Items - [fiMeta];
   FDSP.Params.Clear;

   with FDSP.Params.Add do
   begin
     Name := '@Liste';
     ParamType := ptInput;
     ArrayType := atTable;
     DataType := ftDataSet;
     DataTypeName := 'dbo.UDTT_Test';  // SQL Server TYPE adı
   end;

   FDSP.ParamByName('@Liste').AsDataSet := LTable;

   FDSP.Open;

 finally
   LTable.Free;
 end;
end;
end.


object Form1: TForm1
 Left = 0
 Top = 0
 Caption = 'Form1'
 ClientHeight = 563
 ClientWidth = 840
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -12
 Font.Name = 'Segoe UI'
 Font.Style = []
 TextHeight = 15
 object DBGrid1: TDBGrid
   Left = 47
   Top = 88
   Width = 545
   Height = 153
   DataSource = DSSP
   TabOrder = 0
   TitleFont.Charset = DEFAULT_CHARSET
   TitleFont.Color = clWindowText
   TitleFont.Height = -12
   TitleFont.Name = 'Segoe UI'
   TitleFont.Style = []
 end
 object Button1: TButton
   Left = 120
   Top = 272
   Width = 105
   Height = 25
   Caption = 'Button1'
   TabOrder = 1
   OnClick = Button1Click
 end
 object FDConn: TFDConnection
   LoginPrompt = False
   Left = 192
   Top = 24
 end
 object FDSP: TFDStoredProc
   Connection = FDConn
   Left = 285
   Top = 25
 end
 object DSSP: TDataSource
   DataSet = FDSP
   Left = 381
   Top = 25
 end
end
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla
#2
Sorunun asıl problemi 2 noktada

1. Doğru SQL Driver olmalı

FireDAC ile SQL Eski driverları uyumlu çalışmıyor. yani Native Client 11 yada SQL ODBC Driver sorun cıkarıyor
FireDAC ODBC Driver 17 ve Üstünün makinede kurulu olmasını arıyor.

2. Doğru Parametre
ArrayType := atArray olarak set edilmeli

    with FDSP.Params.Add do
    begin
     Name := '@Liste';
     ParamType := ptInput;
     ArrayType := atArray; //Dikkat En kilit kısım burası eğer atTable olursa sistem calismiyor
     DataType := ftDataSet;
     DataTypeName := 'dbo.UDTT_Test';
   end;


Çalışan ve Alınan hataya göre basit bir örnek

procedure TForm1.Button1Click(Sender: TObject);
var
 LTable: TFDMemTable;
 LErr: string;
begin
 LTable := TFDMemTable.Create(nil);
 try
   LTable.FieldDefs.Clear;
   LTable.FieldDefs.Add('SiraNo', ftInteger);
   LTable.CreateDataSet;
   LTable.Open;

   LTable.Append;
   LTable.FieldByName('SiraNo').AsInteger := 1;
   LTable.Post;

   LTable.Append;
   LTable.FieldByName('SiraNo').AsInteger := 2;
   LTable.Post;

   LTable.Append;
   LTable.FieldByName('SiraNo').AsInteger := 3;
   LTable.Post;

   FDSP.Close;
   FDSP.Unprepare;
   FDSP.StoredProcName := 'dbo.UTP_Test';
   FDSP.FetchOptions.Items := FDSP.FetchOptions.Items - [fiMeta];
   FDSP.Params.Clear;

   with FDSP.Params.Add do
   begin
     Name := '@Liste';
     ParamType := ptInput;
     ArrayType := atArray; //Dikkat En kilit kısım burası eğer atTable olursa sistem calismiyor
     DataType := ftDataSet;
     DataTypeName := 'dbo.UDTT_Test';
   end;

   FDSP.ParamByName('@Liste').AsDataSet := LTable;

   try
     FDSP.Open;
   except
     on E: Exception do
     begin
       LErr := UpperCase(E.Message);

       if (Pos('DATA TYPE IS NOT SUPPORTED', LErr) > 0) and
          ((Pos('[@LISTE]', LErr) > 0) or (Pos('[LISTE]', LErr) > 0)) then
       begin
         MessageDlg(
           'SQL ODBC Driver 17 veya Üstü değil veya ilgili sürücüyü kullanamıyor.' + sLineBreak +
           'Lütfen SQL Server için ODBC Driver 18 kurulumunu resmi sitesinden indirip yapınız.',
           mtError, [mbOK], 0
         );
         Exit;
       end;

       raise;
     end;
   end;

 finally
   LTable.Free;
 end;
end;
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Rest Request Parametre Ekleme m_ekici 9 479 09-02-2026, Saat: 00:33
Son Yorum: m_ekici
  Video Oynatma Hakkında adelphiforumz 7 844 17-12-2025, Saat: 07:36
Son Yorum: mrmarman
  nduWlanAPI Kullanımı hakkında nurah 3 803 09-09-2025, Saat: 09:33
Son Yorum: RAD Coder
  AES Şifreleme Hakkında tmrksmt 25 5.844 06-09-2025, Saat: 22:12
Son Yorum: delphi.developer
  SuperObject dosyaları hakkında adelphiforumz 2 622 18-06-2025, Saat: 11:02
Son Yorum: engerex



Konuyu Okuyanlar: 1 Ziyaretçi