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

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

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


当前回答

尽管这是一个较旧的线程,但有一种较新的方法可以做到这一点,它可以避免旧版本SQL Server中IDENTITY列的一些缺陷,比如服务器重新启动后标识值的空白。序列在SQL Server 2016和转发中可用,这是一种较新的方法,使用TSQL创建SEQUENCE对象。这允许您在SQL Server中创建自己的数字序列对象,并控制它如何递增。

这里有一个例子:

CREATE SEQUENCE CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  

然后在TSQL中,您可以执行以下操作来获得下一个序列ID:

SELECT NEXT VALUE FOR CountBy1 AS SequenceID
GO

下面是CREATE SEQUENCE和NEXT VALUE FOR的链接

其他回答

从MSDN

@@IDENTITY、SCOPE_IDENTITY和IDENT_CURRENT是类似的函数,它们返回插入到表的IDENTITY列中的最后一个值。 @@IDENTITY和SCOPE_IDENTITY将返回当前会话中在任何表中生成的最后一个标识值。然而,SCOPE_IDENTITY只返回当前范围内的值;@@IDENTITY不受特定范围的限制。 IDENT_CURRENT不受作用域和会话的限制;它仅限于指定的表。IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值。有关更多信息,请参见IDENT_CURRENT。

IDENT_CURRENT是一个以表作为参数的函数。 当你在表上有一个触发器时,@@IDENTITY可能返回令人困惑的结果 大多数时候SCOPE_IDENTITY是你的英雄。

尽管这是一个较旧的线程,但有一种较新的方法可以做到这一点,它可以避免旧版本SQL Server中IDENTITY列的一些缺陷,比如服务器重新启动后标识值的空白。序列在SQL Server 2016和转发中可用,这是一种较新的方法,使用TSQL创建SEQUENCE对象。这允许您在SQL Server中创建自己的数字序列对象,并控制它如何递增。

这里有一个例子:

CREATE SEQUENCE CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  

然后在TSQL中,您可以执行以下操作来获得下一个序列ID:

SELECT NEXT VALUE FOR CountBy1 AS SequenceID
GO

下面是CREATE SEQUENCE和NEXT VALUE FOR的链接

创建一个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';

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

SCOPE_IDENTITY是使用当前SQL Connection插入的最后一个标识,并且在当前作用域中——也就是说,如果在插入之后根据触发器插入了第二个identity,那么它将不会反映在SCOPE_IDENTITY中,只反映在您执行的插入中。坦率地说,我从来没有理由使用它。

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

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

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

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

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

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