协慌网

登录 贡献 社区

获取插入行的标识的最佳方法是什么?

获取插入行的IDENTITY的最佳方法是什么?

我知道@@IDENTITYIDENT_CURRENT以及SCOPE_IDENTITY但不了解每个附带的利弊。

有人可以解释一下这些差异,以及何时应该使用它们?

答案

  • @@IDENTITY返回在所有范围内为当前会话中的任何表生成的最后一个标识值。 你需要在这里小心 ,因为它跨越范围。您可以从触发器获取值,而不是当前语句。

  • SCOPE_IDENTITY()返回为当前会话中的任何表和当前范围生成的最后一个标识值。 一般你想要使用什么

  • IDENT_CURRENT('tableName')返回在任何会话和任何范围内为特定表生成的最后一个标识值。这使您可以指定您想要该值的表,以防上述两个不是您需要的( 非常罕见 )。此外,正如 @ Guy Starbuck 所提到的,“如果你想获得未插入记录的表的当前 IDENTITY 值,你可以使用它。”

  • INSERT语句的OUTPUT子句将允许您访问通过该语句插入的每一行。由于它的范围是特定的声明,因此它比上面的其他函数更直接 。但是,它更冗长 (您需要插入表变量 / 临时表然后查询),即使在回滚语句的错误情况下,它也会给出结果。也就是说,如果您的查询使用并行执行计划,这是获取身份的唯一保证方法 (不能关闭并行性)。但是,它触发器之前执行不能用于返回触发器生成的值。

我相信检索插入的 id 的最安全和最准确的方法是使用输出子句。

例如(摘自以下MSDN文章)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

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

@@IDENTITY返回客户端与数据库连接所插入的最后一个内容的 id。
大部分时间这种方法都可以正常工作,但有时触发器会插入一个你不知道的新行,你将从这个新行中获取 ID,而不是你想要的那个

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

IDENT_CURRENT返回任何人插入的最后一个 ID。如果某个其他应用程序恰好在不合适的时间插入另一行,您将获得该行的 ID 而不是您的 ID。

如果您想安全地玩,请始终使用SCOPE_IDENTITY() 。如果您坚持使用@@IDENTITY并且有人决定稍后添加触发器,那么您的所有代码都将中断。