使用 SQL 服务器 table 值参数而不在 SQL 服务器上创建类型

Use SQL Server table-valued parameters without creating a type on the SQL Server

我正在尝试在单个参数(table 值参数)上传递多个值,它在示例后工作正常

C:\Users\Public\Documents\Embarcadero\Studio.0\Samples\Object Pascal\Database\FireDAC\Samples\DBMS Specific\MSSQL\TVP

SQL:

create type TVPType as table(Code integer, Name varchar(100), RegDate datetime, Notes varchar(max))
go

create table TVPTab(Code integer, Name varchar(100), RegDate datetime, Notes varchar(max))
go

Delphi:

procedure TForm1.btnQryManualSetupClick(Sender: TObject);
var
  oDS: TFDMemTable;
  i: Integer;
begin
  Start;

  FDQuery2.SQL.Text := 'insert into TVPTab (Code, Name, RegDate, Notes) ' +
    'select Code, Name, RegDate, Notes from :t';
  oDS := TFDMemTable.Create(nil);
  oDS.FieldDefs.Add('Code', ftInteger);
  oDS.FieldDefs.Add('Name', ftString, 100);
  oDS.FieldDefs.Add('RegDate', ftTimeStamp);
  oDS.FieldDefs.Add('Notes', ftMemo);
  FDQuery2.Params[0].DataTypeName := 'TVPType';
  FDQuery2.Params[0].AsDataSet := oDS;

  (FDQuery2.Params[0].AsDataSet as TFDMemTable).EmptyDataSet;
  for i := 1 to C_Recs do
    with FDQuery2.Params[0].AsDataSet do begin
      Append;
      Fields[0].AsInteger := i;
      Fields[1].AsString := 'str' + IntToStr(i * 10);
      Fields[2].AsDateTime := Now() + i;
      Fields[3].AsString := StringOfChar('x', 1000);
      Post;
    end;

  FDConnection1.StartTransaction;
  FDQuery2.Execute;
  FDConnection1.Commit;

  Done('TVP Qry manual setup');
end;

此代码的问题是它迫使我在服务器上创建一个类型(在本例中为 TVPType 类型),我想使用这些 table 值的参数而不必创建服务器上的任何对象。

可以吗?.我已尝试将参数定义为 ftDataset,但出现错误:无法找到数据类型 READONLY。

procedure TForm1.btnQryManualSetupClick(Sender: TObject);
var
  oDS: TFDMemTable;
  i: Integer;
begin
  Start;

  FDQuery2.SQL.Text := 'insert into TVPTab (Code, Name, RegDate, Notes) ' +
    'select Code, Name, RegDate, Notes from :t';
  oDS := TFDMemTable.Create(nil);
  oDS.FieldDefs.Add('Code', ftInteger);
  oDS.FieldDefs.Add('Name', ftString, 100);
  oDS.FieldDefs.Add('RegDate', ftTimeStamp);
  oDS.FieldDefs.Add('Notes', ftMemo);
  //FDQuery2.Params[0].DataTypeName := 'TVPType';
  FDQuery2.Params[0].DataType := ftDataset;
  FDQuery2.Params[0].AsDataSet := oDS;

  (FDQuery2.Params[0].AsDataSet as TFDMemTable).EmptyDataSet;
  for i := 1 to C_Recs do
    with FDQuery2.Params[0].AsDataSet do begin
      Append;
      Fields[0].AsInteger := i;
      Fields[1].AsString := 'str' + IntToStr(i * 10);
      Fields[2].AsDateTime := Now() + i;
      Fields[3].AsString := StringOfChar('x', 1000);
      Post;
    end;

  FDConnection1.StartTransaction;
  FDQuery2.Execute;
  FDConnection1.Commit;

  Done('TVP Qry manual setup');
end;

没有。如果您的多个值只是一行,您可以考虑将它们作为逗号分隔的字符串传递,然后使用 STRING_SPLIT 函数,或使用临时或永久表来存储多行值。