64

I have seen various methods used when retrieving the value of a primary key identity field after insert.

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

Returning a table of identities following insert:

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

What method is proper or better? Is the OUTPUT method scope-safe?

The second code snippet was borrowed from SQL in the Wild

4

8 回答 8

76

It depends on what you are trying to do...

@@IDENTITY

Returns the last IDENTITY value produced on a connection, regardless of the table that produced the value, and regardless of the scope of the statement that produced the value. @@IDENTITY will return the last identity value entered into a table in your current session. @@IDENTITY is limited to the current session and is not limited to the current scope. For example, if you have a trigger on a table that causes an identity to be created in another table, you will get the identity that was created last, even if it was the trigger that created it.

SCOPE_IDENTITY()

Returns the last IDENTITY value produced on a connection and by a statement in the same scope, regardless of the table that produced the value. SCOPE_IDENTITY() is similar to @@IDENTITY, but it will also limit the value to your current scope. In other words, it will return the last identity value that you explicitly created, rather than any identity that was created by a trigger or a user defined function.

IDENT_CURRENT()

Returns the last IDENTITY value produced in a table, regardless of the connection and scope of the statement that produced the value. IDENT_CURRENT is limited to a specified table, but not by connection or scope.

于 2009-01-26T21:28:17.307 回答
15

请注意,有一个错误scope_identity()-@@identity请参阅 MS Connect:https ://web.archive.org/web/20130412223343/https://connect.microsoft.com/SQLServer/feedback/details/328811/scope-identity-sometimes -返回不正确的值

引用(来自微软):

我强烈建议在所有情况下都使用OUTPUT而不是。@@IDENTITY这只是读取身份和时间戳的最佳方式。

编辑添加:现在可能已修复。Connect 给我一个错误,但请参阅:

Scope_Identity() 返回不正确的值已修复?

于 2009-09-15T14:47:28.070 回答
11

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
)
于 2014-12-08T18:53:48.413 回答
6

@@Identity is the old school way. Use SCOPE_IDENTITY() in all instances going forward. See MSDN for the repercussions of using @@IDENTITY (they're bad!).

于 2009-01-26T21:22:19.767 回答
4

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

对于多行,OUTPUT/OUTPUT INTO 是您最好的新朋友,也是重新查找行并插入另一个表的替代方法。

于 2009-01-26T22:25:58.220 回答
3

There is another method available in SQL Server 2005 that is outlined in SQL in the Wild.

This will allow you to retrieve multiple identities after insert. Here's the code from the blog post:

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values
于 2009-01-26T21:22:18.270 回答
3

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

您需要担心的不仅仅是触发因素。导致创建标识符的任何类型的嵌套操作(例如存储过程)都可能更改@@IDENTITY 的值。

对 scope_identity 的另一票...

于 2009-01-26T21:33:09.370 回答
1

使用@@IDENTITY 时要小心...

http://dotnetgalactics.wordpress.com/2009/10/28/scope-identity-vs-identity/

于 2009-11-02T15:07:41.700 回答