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

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

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


当前回答

获取新插入行的标识的最好(也就是最安全的)方法是使用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)

其他回答

我和其他人说的是一样的,所以每个人都是对的,我只是想让它更清楚。

@@IDENTITY返回客户端连接到数据库时插入的最后一个对象的id。 大多数情况下,这工作得很好,但有时触发器会插入一个您不知道的新行,您将从这个新行获得ID,而不是您想要的行

SCOPE_IDENTITY()解决了这个问题。它返回您在发送给数据库的SQL代码中插入的最后一个内容的id。如果触发器去创建额外的行,它们不会导致返回错误的值。万岁

IDENT_CURRENT返回任何人插入的最后一个ID。如果其他应用在不幸的时间插入了另一行,你会得到那一行的ID,而不是你的。

如果想要安全起见,请始终使用SCOPE_IDENTITY()。如果您坚持使用@@IDENTITY,然后有人决定稍后添加一个触发器,那么您的所有代码都将崩溃。

我不能与其他版本的SQL Server对话,但在2012年,直接输出工作得很好。您不需要为临时表而烦恼。

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

顺便说一下,这种技术也适用于插入多行。

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

输出

ID
2
3
4

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

IDENT_CURRENT('tableName')

创建一个uuid并将其插入到列中。然后,您可以很容易地用uuid标识行。这是唯一可以实现的100%有效的解决方案。所有其他的解都太复杂了,或者在相同的边缘情况下不起作用。 例如:

1)创建行

INSERT INTO table (uuid, name, street, zip) 
        VALUES ('2f802845-447b-4caa-8783-2086a0a8d437', 'Peter', 'Mainstreet 7', '88888');

2)获取创建行

SELECT * FROM table WHERE uuid='2f802845-447b-4caa-8783-2086a0a8d437';

总是使用scope_identity(),永远不需要其他任何东西。