是否需要“BEGIN TRAN”才能获得正确的SCOPE_IDENTITY?

时间:2013-06-12 22:25:12

标签: c# .net sql sql-server sql-server-2012

我正在使用SqlCommand,如此:

command.CommandText = "INSERT INTO ... VALUES ...; SELECT SCOPE_IDENTITY();";

这是否足够,还是我需要BEGIN TRAN等? (提到here。)

当然,我先尝试过,它运行正常。但即使有两个同时插入,它还能正常工作吗? (而且我不确定如何测试那个。)

3 个答案:

答案 0 :(得分:5)

您不需要BEGIN TRAN。没有它,Scope_Identity()运行正常。即使有“同时插入”。这是函数的重点 - 仅返回当前作用域的答案。

请注意,在少于SQL Server 2012的情况下,并行性可能会中断Scope_Identity(),因此必须WITH (MAXDOP 1)语句中使用查询提示INSERT你希望它在100%的时间内正常工作。你可以read about this problem on Microsoft Connect。 (SQL Server 2008 R2 Service Pack 1的累积更新包5中为theoretically fixed,但有些人似乎认为可能不是100%真实。)

SQL Server 2005及更高版本中还有OUTPUT子句,这是通过向客户端发送行集或输出到表来返回有关INSERT的数据的另一种方法。请注意,接收行集实际上并不能证明INSERT已正确提交...因此您应该在存储过程中使用SET XACT_ABORT ON;。这是OUTPUT的一个例子:

CREATE TABLE @AInsert(IDColumn);

INSERT dbo.TableA (OtherColumn) -- not the identity column
OUTPUT Inserted.IDColumn -- , Inserted.OtherColumn, Inserted.ColumnWithDefault
   INTO @AInsert
SELECT 'abc';

-- Do something with @AInsert, which contains all the `IDColumn` values
-- that were inserted into the table. You can insert all columns, too,
-- as shown in the comments above

答案 1 :(得分:2)

不完全是您的问题的答案,但如果您使用的是SQL Server 2005及更高版本,请考虑使用OUTPUT子句,请查看此so answer以获取完整示例,这很简单,可以实现

INSERT dbo.MyTable (col1, col2, col3)
OUTPUT INSERTED.idCol
VALUES ('a', 'b', 'c')

答案 2 :(得分:1)

Scope_Identity和Begin Tran独立工作,当您可能希望在查询中的给定点回滚或提交事务时,使用begin tran。