我检查了SCOPE_IDENTITY()的文档,并说"范围是一个模块:存储过程,触发器,函数或批处理." 当我在SSMSE中运行查询时,这很简单,但在C#中我使用SqlCommand来执行我的语句.
问题是:那里的范围是什么?在一个连接下执行后续命令是否等同于批处理?或者也许每个命令都在不同的范围内,我需要一个事务才能使用它?
我建议将您的C#命令和T-SQL"批处理"视为彼此完全分离.
可以将SQLCommand视为您的执行包装器,其中构成批处理的实际定义由T-SQL语言定义和控制.
您的会话范围在Connection对象级别维护.
你可能会发现以下MSDN论坛帖子有趣的阅读.注意初始示例如何执行两个单独的SQL命令,但第二个调用的SCOPE_IDENITY()可以看到前一个调用的结果.这是因为当前范围在连接级别是可见的.
SQLCommand With Parameters和Scope_Indentity
为了完整解释,使用参数不起作用的原因,如后面链接示例中所示,是因为sp_executesql在其自己的范围内执行,因此无法查看连接的范围.
[编辑]
进一步阅读更好奇的读者,请在下面找到VB.NET代码,它提供了在单个Connection上执行两个单独命令的示例,第二个命令成功发出SCOPE_IDENTITY()函数.
源代码可以在SSIS包Task的SCRIPT组件中执行.您还需要编辑环境的连接详细信息,并创建引用的表对象.
创建表脚本:
create table TestTable
(
ID int identity(1,1) primary key not null,
SomeNumericData int not null
);
Run Code Online (Sandbox Code Playgroud)
VB.NET源码清单:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Data.SqlClient.SqlConnection
Imports Windows.Forms.MessageBox
Public Class ScriptMain
Public Sub Main()
'
' Add your code here
Dim oCnn As New Data.SqlClient.SqlConnection
Dim sSQL As String
Dim sSQL2 As String
Dim resultOne As Integer
Dim resultTwo As Integer
Dim messageBox As Windows.Forms.MessageBox
resultOne = 0
resultTwo = 0
oCnn.ConnectionString = "Server=ServerName;Database=DatabaseName;Trusted_Connection=true"
sSQL = "INSERT INTO TestTable(SomeNumericData) VALUES(666) "
sSQL2 = "SELECT SCOPE_IDENTITY()"
Dim oCmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL, oCnn)
Dim oCmd2 As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL2, oCnn)
oCmd.CommandType = CommandType.Text
oCmd.Connection = oCnn
oCnn.Open()
resultOne = oCmd.ExecuteNonQuery()
resultTwo = Convert.ToInt32(oCmd2.ExecuteScalar())
oCnn.Close()
messageBox.Show("result1:" + resultOne.ToString + Environment.NewLine + "result2: " + resultTwo.ToString)
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)