C#中的SCOPE_IDENTITY – 范围

我检查了SCOPE_IDENTITY()的文档,并说“范围是一个模块:存储过程,触发器,函数或批处理。” 当我在SSMSE中运行查询时,这很简单,但在C#中我使用SqlCommand来执行我的语句。

问题是:那里的范围是什么? 在一个连接下执行后续命令是否等同于批处理? 或者也许每个命令都在不同的范围内,我需要一个事务才能使用它?

我建议将您的C#命令和T-SQL“批处理”视为彼此完全分离。

可以将SQLCommand视为您的执行包装器,其中构成批处理的实际定义由T-SQL语言定义和控制。

您的会话范围在Connection对象级别维护。

你可能会发现以下MSDN论坛post有趣的阅读。 注意初始示例如何执行两个单独的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 ); 

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 

我相信范围仅适用于单个命令,而不适用于整个连接。

 strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT SCOPE_IDENTITY()" SQLCommand.CommandText = strSQL Id = SQLCommand.ExecuteScalar() 

在上面的代码中, strSQL是一个完整的作用域,它总是返回相关insert语句的@@ identity值。

所以后续命令将有自己的范围。