获得插入行身份的最佳方法?

时间:2020-03-05 18:47:19  来源:igfitidea点击:

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

我了解@@ IDENTITYIDENT_CURRENTSCOPE_IDENTITY,但不了解它们各自的优缺点。

有人可以解释这些差异以及何时应使用它们吗?

解决方案

回答

MSDN

@@IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT are similar functions in that they return the last value inserted into the IDENTITY column of a table.
  
  @@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.
  
  IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.
  • IDENT_CURRENT是一个以表为参数的函数。
  • 当表上有触发器时,@@ IDENTITY可能会返回令人困惑的结果
  • SCOPE_IDENTITY通常是英雄。

回答

  • @@ IDENTITY返回所有会话中为当前会话中的任何表生成的最后一个标识值。我们需要小心,因为它是跨作用域的。我们可以从触发器获取值,而不是当前语句。
  • SCOPE_IDENTITY()返回为当前会话和当前范围中的任何表生成的最后一个标识值。通常,我们要使用什么。
  • IDENT_CURRENT('tableName')返回在任何会话和任何作用域中为特定表生成的最后一个标识值。这可以让我们指定要从哪个表中获取值,以防上述两个表不是我们真正需要的表(非常罕见)。另外,正如@Guy Starbuck所提到的,"如果要获取尚未插入记录的表的当前IDENTITY值,则可以使用它。"
  • 通过INSERT语句的OUTPUT子句,我们可以访问通过该语句插入的每一行。由于它是针对特定语句的,因此它比上面的其他函数更直接。但是,它有些冗长(我们需要将其插入到表变量/临时表中,然后对其进行查询),即使在语句回滚的错误情况下,它也可以提供结果。就是说,如果查询使用并行执行计划,则这是获得身份的唯一保证方法(缺少关闭并行性)。但是,它在触发器之前执行,不能用于返回触发器生成的值。

回答

@@ IDENTITY是使用当前SQL连接插入的最后一个身份。这是从插入存储过程返回的一个好值,在该存储过程中,我们只需要为新记录插入标识,而不必担心之后是否添加了更多行。

SCOPE_IDENTITY是使用当前SQL连接在当前作用域中插入的最后一个标识,即,如果在插入后基于触发器插入了第二个IDENTITY,它将不会反映在SCOPE_IDENTITY中,仅反映在执行的插入中。坦白说,我从来没有理由使用它。

IDENT_CURRENT(tablename)是最后插入的标识,无论连接或者作用域如何。如果要获取尚未在其中插入记录的表的当前IDENTITY值,则可以使用此方法。

回答

我说的是与其他人相同的话,所以每个人都是对的,我只是想让事情变得更清楚。

@@ IDENTITY返回客户端连接到数据库所插入的最后一个事物的ID。
在大多数情况下,这可以正常工作,但有时会触发一个触发器,插入我们不知道的新行,并且我们将从新行中获取ID,而不是我们想要的行

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

IDENT_CURRENT返回任何人插入的最后一个ID。如果某个其他应用恰巧在不幸的时间插入另一行,则我们将获得该行的ID,而不是ID。

如果我们想安全地使用它,请始终使用SCOPE_IDENTITY()。如果我们坚持使用@@ IDENTITY,并且以后有人决定添加触发器,则所有代码都会中断。

回答

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