@@ 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是您新的最好的朋友,可以重新查找行并插入到另一个表中。
在使用@@ IDENTITY时要谨慎
http://dotnetgalactics.wordpress.com/2009/10/28/scope-identity-vs-identity/