Sql server SQL Server:未使用ODBC SQLExecDirect完全执行主键冲突的批处理

Sql server SQL Server:未使用ODBC SQLExecDirect完全执行主键冲突的批处理,sql-server,odbc,Sql Server,Odbc,默认情况下,在SQL Server中,主键冲突不会中止批处理。使用SQL Server Management Studio SSMS可以轻松复制此行为,例如: 创建表dbo.A id int主键 插入dbo.A值0-有效! 插入dbo.A值0-主键冲突 插入dbo.A值0-主键冲突 插入dbo.A值0-主键冲突 插入dbo.A值1-有效! 从dbo.A中选择* > AOSS,当我使用ODBC函数Sql ExcRead运行C++程序的类似代码时,我得到了非确定性行为,即在两个主键违反后剩余的批被

默认情况下,在SQL Server中,主键冲突不会中止批处理。使用SQL Server Management Studio SSMS可以轻松复制此行为,例如:

创建表dbo.A id int主键 插入dbo.A值0-有效! 插入dbo.A值0-主键冲突 插入dbo.A值0-主键冲突 插入dbo.A值0-主键冲突 插入dbo.A值1-有效! 从dbo.A中选择*

> AOSS,当我使用ODBC函数Sql ExcRead运行C++程序的类似代码时,我得到了非确定性行为,即在两个主键违反后剩余的批被中止,其余的未执行。 考虑以下循环,该循环将insert语句添加到批处理并执行它:

对于int i=0;i<100++我 { ssSql 这是ODBC、驱动程序还是SQL Server的缺陷/限制

驱动程序。所有驱动程序都简化了客户机/服务器交互,使编程更容易,但每一次简化都会产生一些特殊情况

该批处理将向客户机返回各种消息,包括行数通知和错误消息,更复杂的是,出于性能原因,SQL Server将在服务器上缓冲消息

因此,可能发生的情况是,驱动程序在看到第一条错误消息时中止批处理,这是完全可以自由执行的。但是,当它看到第一条错误消息时,由于服务器端消息缓冲,与发送第一条错误消息时不同


最佳做法是始终使用XACT\U ABORT ON,如果要将一组行发送到SQL Server并插入不存在的行,则可以手工插入…如果不存在查询,请使用TSQL的MERGE或在索引上设置IGNORE\U DUP\U键。

检查XACT\U ABORT是开还是关?@OPTIONS&16384=16384如果0,则关闭。最佳做法是打开它,不要向数据库发送坏密钥,请执行单独的操作checking@Charlieface:默认情况下它是关闭的,我希望这样做,以便插入不存在的内容,并将主键冲突报告给客户端。正如我所说的,您确定XACT_ABORT已关闭吗?为什么不检查SQLExecDirect的返回结果?错误代码ys不知道有多少次插入有效,以及何时/如果批处理被中止,这实际上从来没有发生过。我知道MERGE和类似的方法是为了防止主键冲突。但其想法是插入不存在的内容,并在客户端记录主键violoation的发生。SSMS和sqlcmd工作正常ed-显然他们不使用ODBC,但使用OLEDB!?您可以只在每个语句中插入一行,或者在TRY/CATCH中包装每个插入。大问题:为什么Microsoft的ODBC驱动程序会显示这种行为?在我看来,这看起来像是一个缺陷,甚至不是一个bug。特别是在SSMS和sqlcmd的行为符合预期的情况下。@MarkusNiß我还了解了为什么最佳实践是保持XACT_中止,并通过T-SQL执行错误检查。您只需将所有失败的行选择回客户端,这并不是什么大问题。至于这可能是缺陷还是bug。但旧的SQL Server驱动程序显示了这种行为,这可能是一个突破性的改变。