@@ IDENTITY,SCOPE_IDENTITY(),OUTPUT和其他检索最后一个标识的方法

我已经看到插入后检索主键标识字段的值时使用的各种方法。

declare @t table ( id int identity primary key, somecol datetime default getdate() ) insert into @t default values select SCOPE_IDENTITY() --returns 1 select @@IDENTITY --returns 1 

在插入后返回一个身份表:

 Create Table #Testing ( id int identity, somedate datetime default getdate() ) insert into #Testing output inserted.* default values 

什么方法是适当的或更好的? OUTPUT方法是否是范围安全的?

第二个代码片段是从野外SQL中借用的

这取决于你想要做什么…

@@ IDENTITY

返回连接上生成的最后一个IDENTITY值,而不考虑产生该值的表,而不考虑产生该值的语句的范围。 @@ IDENTITY将返回在当前会话中input到表中的最后一个标识值。 @@ IDENTITY仅限于当前会话,不限于当前范围。 例如,如果在表上有一个触发器,可以在另一个表中创build一个标识,则将获得最后创build的标识,即使它是创build该标识的触发器。

SCOPE_IDENTITY()

无论生成该值的表是什么,都会返回连接和同一范围内的语句生成的最后一个IDENTITY值。 SCOPE_IDENTITY()与@@ IDENTITY类似,但它也会将值限制在当前范围内。 换句话说,它将返回您显式创build的最后一个标识值,而不是由触发器或用户定义函数创build的任何标识。

IDENT_CURRENT()

返回表中生成的最后一个IDENTITY值,而不pipe生成该值的语句的连接和范围如何。 IDENT_CURRENT仅限于指定的表,但不能通过连接或范围。

请注意,scope_identity()和@@ identity中存在一个错误 – 请参阅connect: https ://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

引用(来自微软):

“我高度推荐在所有情况下使用OUTPUT而不是@@ IDENTITY,这是读取身份和时间戳的最好方法。

编辑补充:现在可能已经修复了,Connect给了我一个错误,但是看到:

Scope_Identity()返回不正确的值吗?

@@身份是旧的方式。 在所有前进的实例中使用SCOPE_IDENTITY()。 请参阅MSDN使用@@ IDENTITY(他们是坏的!)的影响。

尝试获取刚刚插入的行的标识时,几乎没有理由使用除OUTPUT子句之外的任何内容。 OUTPUT子句是范围和表安全的。

下面是一个插入单行后获取id的简单示例。

 DECLARE @Inserted AS TABLE (MyTableId INT); INSERT [MyTable] (MyTableColOne, MyTableColTwo) OUTPUT Inserted.MyTableId INTO @Inserted VALUES ('Val1','Val2') SELECT MyTableId FROM @Inserted 

OUTPUT子句的详细文档: http : //technet.microsoft.com/en-us/library/ms177564.aspx


 -- table structure for example: CREATE TABLE MyTable ( MyTableId int NOT NULL IDENTITY (1, 1), MyTableColOne varchar(50) NOT NULL, MyTableColTwo varchar(50) NOT NULL ) 

SQL Server 2005中还有另一种在Wild中的SQL中概述的方法 。

这将允许您在插入后检索多个身份。 以下是博客文章中的代码:

 Create Table #Testing ( id int identity, somedate datetime default getdate() ) insert into #Testing output inserted.* default values 

对戈德克的回答的一个小修改:

这不只是触发器,你需要担心。 任何types的嵌套操作(如存储过程)都会导致标识符被创build,从而可能会更改@@ IDENTITY的值。

另一个投票scope_identity …

SCOPE_IDENTITY对于单行是足够的,除了出于某种原因需要查看中间TRIGGER的结果(为什么?)之外,build议使用SCOPE_IDENTITY。

对于多行,OUTPUT / OUTPUT INTO是您新的最好的朋友,可以重新查找行并插入到另一个表中。