我应该如何获得插入行的身份?

我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。

谁能解释一下它们的区别,以及我什么时候使用它们?


当前回答

在你的插入语句之后,你需要添加这个。确认插入数据的表名。您将得到当前行,而不是刚才插入语句所影响的行。

IDENT_CURRENT('tableName')

其他回答

从MSDN

@@IDENTITY、SCOPE_IDENTITY和IDENT_CURRENT是类似的函数,它们返回插入到表的IDENTITY列中的最后一个值。 @@IDENTITY和SCOPE_IDENTITY将返回当前会话中在任何表中生成的最后一个标识值。然而,SCOPE_IDENTITY只返回当前范围内的值;@@IDENTITY不受特定范围的限制。 IDENT_CURRENT不受作用域和会话的限制;它仅限于指定的表。IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值。有关更多信息,请参见IDENT_CURRENT。

IDENT_CURRENT是一个以表作为参数的函数。 当你在表上有一个触发器时,@@IDENTITY可能返回令人困惑的结果 大多数时候SCOPE_IDENTITY是你的英雄。

我认为检索插入的id最安全、最准确的方法是使用output子句。

例如(摘自以下MSDN文章)

使用AdventureWorks2008R2; 去 声明@MyTableVar表(NewScrapReasonID smallint, 名字varchar (50), ModifiedDate datetime); 插入生产。ScrapReason 输出插入。ScrapReasonID,插入。名字,插入。ModifiedDate 到@MyTableVar VALUES (N'操作符错误',GETDATE()); ——显示表变量的结果集。 SELECT NewScrapReasonID, Name, ModifiedDate FROM @ mytablear; ——显示表的结果集。 SELECT ScrapReasonID, Name, ModifiedDate 从Production.ScrapReason; 去

获取新插入行的标识的最好(也就是最安全的)方法是使用output子句:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

Add

SELECT CAST(scope_identity() AS int);

插入SQL语句的末尾

NewId = command.ExecuteScalar()

会取回它。

@@IDENTITY返回当前会话中为所有作用域中的任何表生成的最后一个标识值。这里需要小心,因为它是跨作用域的。您可以从触发器获得一个值,而不是当前语句。 SCOPE_IDENTITY()返回当前会话和当前作用域中为任何表生成的最后一个标识值。通常是你想用的。 IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这允许您指定需要从哪个表中获取值,以防上面两个表不是您所需要的(非常罕见)。另外,正如@Guy Starbuck所提到的,“如果您想获得尚未插入记录的表的当前IDENTITY值,则可以使用此方法。” INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。因为它的作用域是特定的语句,所以它比上面的其他函数更直接。但是,它有点啰嗦(您需要将变量/temp表插入到表中,然后再查询),即使在回滚语句的错误场景中,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获得标识的唯一保证方法(除了关闭并行)。但是,它在触发器之前执行,不能用于返回触发器生成的值。