这是一个最小的复制示例。
数据库:
CREATE TABLE temp (x int IDENTITY(1, 1), y int);
代码(使用VBA和ADO):
Public Sub repro()
Dim cn As New Connection
Dim rs1 As New Recordset
Dim cmd As New Command
Dim rs2 As New Recordset
cn.Open "Provider=SQLNCLI11;Server=myServer;Database=myDatabase;Trusted_Connection=Yes"
rs1.Open "SELECT 1", cn, adOpenForwardOnly ' [X] '
cmd.ActiveConnection = cn
cmd.CommandText = "INSERT INTO temp (y) VALUES (1) "
cmd.Execute
rs2.Open "SELECT @@IDENTITY", cn, adOpenStatic
Debug.Print rs2(0).value
rs2.Close
rs1.Close ' [X] '
cn.Close
End Sub
预期结果 Debug.Print
行向调试窗口输出一个整数。
实际结果: Debug.Print
行输出Null
到调试窗口。
备注:
[X]
的行,代码就会按预期工作(最后插入的标识值将写入调试窗口)。SELECT SCOPE_IDENTITY()
添加到INSERT批处理是获取新插入ID的正确方法。这只是用尽可能少的代码重现问题的最小例子。我在修改遗留代码时偶然发现了这个问题。我的问题:这是设计上的行为,还是偶然发现了SQL Server错误?如果是前者,它在哪里记录?
编辑:将两个选项(有和没有[X])与SQL Server Profiler跟踪进行比较,有一个显着的区别:当包含[X]行时,连接显然被删除并重新打开({{1 } { - {1}}在Audit Logout
和Audit Login
之间。我想这可以解释为什么cmd.Execute
不再有效。
这留下了以下问题:为什么ADO(或SQLNCLI11驱动程序?)在一种情况下关闭并重新打开连接而在另一种情况下不重新打开连接?这记录在哪里?
答案 0 :(得分:2)
MARS是一种更好的替代默认行为,实际上允许多个记录集。
会发生什么:
答案 1 :(得分:0)
我注意到你在同一个连接上做两次选择。您是否尝试过启用"多个活动结果集"通过添加" MultipleActiveResultSets = True"你的连接字符串?