Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 FireDAC、阵列DML、SQL Server和标识插入_Sql Server 2008_Delphi_Delphi Xe7_Firedac - Fatal编程技术网

Sql server 2008 FireDAC、阵列DML、SQL Server和标识插入

Sql server 2008 FireDAC、阵列DML、SQL Server和标识插入,sql-server-2008,delphi,delphi-xe7,firedac,Sql Server 2008,Delphi,Delphi Xe7,Firedac,我正在尝试使用Firedac数组DML功能将数据导出到SQL Server。在目标表中,有一个标识列,我需要给它加一个显式值 但我的查询失败,并显示以下错误消息: SQL状态:23000。本地代码:544。消息:[Microsoft][SQL Server] 本机客户端11.0][SQL Server]无法为插入显式值 当identity_INSERT设置为时,表“dic_cities”中的identity列 走开 目标表定义如下: CREATE TABLE dbo.dic_cities (

我正在尝试使用Firedac数组DML功能将数据导出到SQL Server。在目标表中,有一个标识列,我需要给它加一个显式值

但我的查询失败,并显示以下错误消息:

SQL状态:23000。本地代码:544。消息:[Microsoft][SQL Server] 本机客户端11.0][SQL Server]无法为插入显式值 当identity_INSERT设置为时,表“dic_cities”中的identity列 走开

目标表定义如下:

CREATE TABLE dbo.dic_cities (
  id int IDENTITY(1,1) PRIMARY KEY,
  city_name varchar(50) NOT NULL
)
我的代码:

MyFDQuery.Connection.ExecSQL('SET IDENTITY_INSERT dbo.dic_cities ON');  

MyFDQuery.SQL.Text := 'INSERT INTO dbo.dic_cities (id, city_name) VALUES (:id, :city_name)';  

//Populating parameters and preparing the query
{...}

//Execute Array DML query with batch size of 100 
MyFDQuery.Execute(100, 0);  

//Finally, set IDENTITY_INSERT off for the destination table
MyFDQuery.Connection.ExecSQL('SET IDENTITY_INSERT dbo.dic_cities OFF');  
我必须注意,当我使用带参数的常规TFDQuery时(即,当不使用数组DML特性时),一切都很好。但对于阵列DML,它失败了

多年来,我还以类似于上述代码的方式将Array DML用于其他几个DBMS,并取得了成功

那么,如何使用Array DML功能向SQL Server标识列插入显式值呢

更新#2:参见

我还没有完全理解它,但OP的问题似乎非常相似

我已经尝试过构造SQL以使用EXEC

  FDQuery1.SQL.Text := 'EXEC (' + ''''+ sSetIIOn + ';' + sInsert + ';' + sSetIIOff + '''' + ')';
为避免使用sp_executesql,但不幸的是,FD无法正确解析SQL,因此在设置参数时会产生“参数超出范围”错误。
更新:好奇者和好奇者

以下代码在SS2014上无错误地执行,并插入预期的10行:

const
  sEmptyTable = 'delete from dbo.identtest';
  sSetIIOn = 'set identity_insert dbo.identtest ON';
  sSetIIOff = 'set identity_insert dbo.identtest OFF';
  sSelect = 'select * from dbo.identtest';
  sInsert = 'insert dbo.identtest (ID, Name) values(%d, %s)';

procedure TForm2.TestIdentityInsert;
var
  i : Integer;
  S : String;
begin
  FDQuery1.ExecSql(sEmptyTable);
  FDQuery1.ExecSql(sSetIIOn);

  for i := 1 to 10 do begin
    S := Format(sInsert, [i, '''Name' + IntToStr(i) + '''']);
    FDQuery1.ExecSQL(S);
  end;

  FDQuery1.ExecSql(sSetIIOff);
  FDQuery1.Sql.Text := sSelect;
  FDQuery1.Open;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  TestIdentityInsert;
end;
但是,将循环的
替换为

  FDQuery1.SQL.Text := sSetIIOn + ';' + sInsert + ';' + sSetIIOff;

  FDQuery1.Params.ArraySize := Rows;
  for i := 0 to Rows - 1 do begin
    FDQuery1.Params[0].AsIntegers[i] := i;
    FDQuery1.Params[1].AsStrings[i] := 'Name' + IntToStr(i);
  end;
生成引用的异常。我已经使用SSMS Profiler验证了发送到服务器的SQL似乎是正确的(而不是像有时发生的那样,f.I.被MDac层损坏):


因此,问题似乎是为什么使用
sp_executesql
不尊重Identity\u Insert设置,还有其他方法吗?

Leavng aside Array dML,您能否通过检索FDQuery的
OnNewRecord
事件中的下一个Identity值成功地将行插入表中?@MartynA否。我没有尝试过该事件。没有阵列DML,我可以轻松地管理事情。但出于导出速度的原因,我需要数组DML。如果您的问题只是抱怨语法错误,请尝试在Sql Server Management Studio的查询实用程序中使用INSERT语句。@MartynA否。我的问题是如何使用数组DML将显式值插入Sql Server标识列。我更新了我的问题以避免误解。您是否使用SSMS的探查器来查看服务器反对的内容,以及如果您的ExecSQL?如果您通过使用if使INSERT语句依赖于其当前值来测试SET_标识值,该怎么办?谢谢您指点我使用探查器。实际上,由于我的代码中有错误,没有执行“SET IDENTITY_INSERT ON”。很高兴您对其进行了排序。如你所见,我的尝试遇到了困难。
exec sp_executesql N'set identity_insert dbo.identtest ON;insert dbo.identtest values(@P1, @P2);set identity_insert dbo.identtest OFF',N'@P1 int,@P2 nvarchar(4000)',0,N'Name0' [etc, repeated 9 times]