【发布时间】:2010-10-12 09:15:51
【问题描述】:
我查看了SCOPE_IDENTITY() 的文档,上面写着“作用域是一个模块:存储过程、触发器、函数或批处理。”当我在 SSMSE 中运行查询时,这很简单,但在 C# 中,我使用 SqlCommand 来执行我的语句。
问题是:那里的范围是什么?在一个连接下执行后续命令是否等同于批处理?或者也许每个命令都在不同的范围内,我需要一个事务才能工作?
【问题讨论】:
标签: c# sql-server
我查看了SCOPE_IDENTITY() 的文档,上面写着“作用域是一个模块:存储过程、触发器、函数或批处理。”当我在 SSMSE 中运行查询时,这很简单,但在 C# 中,我使用 SqlCommand 来执行我的语句。
问题是:那里的范围是什么?在一个连接下执行后续命令是否等同于批处理?或者也许每个命令都在不同的范围内,我需要一个事务才能工作?
【问题讨论】:
标签: c# sql-server
我建议将 C# 命令和 T-SQL“批处理”视为彼此完全独立的。
仅将 SQLCommand 视为您的执行包装器,其中构成批处理的实际定义由 T-SQL 语言定义和控制。
您的会话范围在 Connection 对象级别维护。
您可能会发现以下 MSDN 论坛帖子很有趣。注意第一个示例如何执行两个单独的 SQL 命令,但第二个调用的 SCOPE_IDENITY() 可以看到前一个调用的结果。这是因为当前范围在连接级别是可见的。
SQLCommand With Parameters and Scope_Indentity
为了解释的完整性,使用参数不起作用的原因,如后面链接示例中所示,是因为 sp_executesql 在它自己的范围内执行,因此看不到连接的范围。
[编辑]
更多好奇读者的进一步阅读,请在下面找到 VB.NET 代码,该代码提供了在单个连接上执行两个单独命令的示例,第二个命令成功发出 SCOPE_IDENTITY() 函数。
可以从 SSIS 包任务的 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是一个完整的作用域,它总是返回关联插入语句的@@identity值。
因此后续命令将有自己的范围。
【讨论】: