我已经看到在插入后检索主键标识字段的值时使用的各种方法。
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 in the Wild
借来的答案 0 :(得分:70)
这取决于你想要做什么......
@@ IDENTITY
返回连接上生成的最后一个IDENTITY值,无论生成该值的表如何,也不管生成该值的语句的范围如何。 @@ IDENTITY将返回在当前会话中输入到表中的最后一个标识值。 @@ IDENTITY仅限于当前会话,不限于当前范围。例如,如果您在表上触发了导致在另一个表中创建标识的触发器,您将获得最后创建的标识,即使它是创建它的触发器。
SCOPE_IDENTITY()
返回在连接上生成的最后一个IDENTITY值以及同一作用域中的语句,而不管生成该值的表是什么。 SCOPE_IDENTITY()类似于@@ IDENTITY,但它也会将值限制为当前范围。换句话说,它将返回您显式创建的最后一个标识值,而不是由触发器或用户定义函数创建的任何标识。
IDENT_CURRENT()
返回表中生成的最后一个IDENTITY值,而不管生成该值的语句的连接和范围如何。 IDENT_CURRENT仅限于指定的表,但不受连接或范围的限制。
答案 1 :(得分:12)
请注意,scope_identity()和@@ identity中存在错误 - 请参阅connect:https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811
引用(来自Microsoft):
“在所有情况下,我都非常推荐使用OUTPUT而不是@@ IDENTITY。这只是阅读身份和时间戳的最佳方式。”
编辑添加:现在可以修复,Connect给我一个错误,但请看:
答案 2 :(得分:8)
在尝试获取刚刚插入的行的标识时,除了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
)
答案 3 :(得分:6)
@@身份是旧学校的方式。在所有实例中使用SCOPE_IDENTITY()。有关使用@@ IDENTITY的影响,请参阅MSDN(它们很糟糕!)。
答案 4 :(得分:3)
SQL Server 2005中还有另一种方法,概述为in SQL in the Wild。
这将允许您在插入后检索多个身份。以下是博客文章中的代码:
Create Table #Testing (
id int identity,
somedate datetime default getdate()
)
insert into #Testing
output inserted.*
default values
答案 5 :(得分:3)
对Godeke答案的一个小小修正:
这不仅仅是你需要担心的触发器。任何导致标识符创建的嵌套操作(如存储过程)都可能会更改@@ IDENTITY的值。
对scope_identity的另一次投票......
答案 6 :(得分:3)
SCOPE_IDENTITY足以满足单行的需求,除非您出于某种原因需要查看中间TRIGGER的结果(为什么?),否则建议使用SCOPE_IDENTITY。
对于多行,OUTPUT / OUTPUT INTO是您最好的朋友,也是重新查找行并插入另一个表的替代方法。
答案 7 :(得分:1)
使用@@ IDENTITY时要小心......
http://dotnetgalactics.wordpress.com/2009/10/28/scope-identity-vs-identity/