我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
我应该如何获得插入行的身份?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不理解它们所附带的含义或影响。
谁能解释一下它们的区别,以及我什么时候使用它们?
当前回答
我不能与其他版本的SQL Server对话,但在2012年,直接输出工作得很好。您不需要为临时表而烦恼。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)
顺便说一下,这种技术也适用于插入多行。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
(...),
(...),
(...)
输出
ID
2
3
4
其他回答
我不能与其他版本的SQL Server对话,但在2012年,直接输出工作得很好。您不需要为临时表而烦恼。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)
顺便说一下,这种技术也适用于插入多行。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
(...),
(...),
(...)
输出
ID
2
3
4
从MSDN
@@IDENTITY、SCOPE_IDENTITY和IDENT_CURRENT是类似的函数,它们返回插入到表的IDENTITY列中的最后一个值。 @@IDENTITY和SCOPE_IDENTITY将返回当前会话中在任何表中生成的最后一个标识值。然而,SCOPE_IDENTITY只返回当前范围内的值;@@IDENTITY不受特定范围的限制。 IDENT_CURRENT不受作用域和会话的限制;它仅限于指定的表。IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值。有关更多信息,请参见IDENT_CURRENT。
IDENT_CURRENT是一个以表作为参数的函数。 当你在表上有一个触发器时,@@IDENTITY可能返回令人困惑的结果 大多数时候SCOPE_IDENTITY是你的英雄。
@@IDENTITY返回当前会话中为所有作用域中的任何表生成的最后一个标识值。这里需要小心,因为它是跨作用域的。您可以从触发器获得一个值,而不是当前语句。 SCOPE_IDENTITY()返回当前会话和当前作用域中为任何表生成的最后一个标识值。通常是你想用的。 IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这允许您指定需要从哪个表中获取值,以防上面两个表不是您所需要的(非常罕见)。另外,正如@Guy Starbuck所提到的,“如果您想获得尚未插入记录的表的当前IDENTITY值,则可以使用此方法。” INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。因为它的作用域是特定的语句,所以它比上面的其他函数更直接。但是,它有点啰嗦(您需要将变量/temp表插入到表中,然后再查询),即使在回滚语句的错误场景中,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获得标识的唯一保证方法(除了关闭并行)。但是,它在触发器之前执行,不能用于返回触发器生成的值。
创建一个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';
获取新插入行的标识的最好(也就是最安全的)方法是使用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)