我需要严格按照当前会话获取特定表中的最后插入行。我无法使用@@IDENTITY,SCOPE_IDENTITY()因为它们将返回ANY表的最后插入的标识。问题IDENT_CURRENT在于它将返回记录的最后插入标识,该记录是针对特定表但针对任何会话的。这对我来说是个问题,因为INSERT多个会话调用了,并且我特别需要特定会话的最后插入记录的标识。
@@IDENTITY
SCOPE_IDENTITY()
IDENT_CURRENT
INSERT
任何指针如何做到这一点?
ps。该INSERT语句不在SPROC内部,因此SPROC解决方案不可行。
谢谢
我知道这不是您似乎想听到的答案,但答案是使用SCOPE_IDENTITY()。您正在考虑的问题( 任何 表的位置)是我们为什么使用SCOPE_IDENTITY()而不是的原因@@IDENTITY。考虑这样一种情况:您有一个带有IDENTITY列的表,并且在该表上有一个插入触发器,该触发器本身插入到带有IDENTITY列的表中。
IDENTITY
CREATE TABLE dbo.Log(LogID INT IDENTITY(100,1), FooID INT); CREATE TABLE dbo.Foo(FooID INT IDENTITY(1,1), name VARCHAR(32)); GO CREATE TRIGGER dbo.Foo_Insert ON dbo.Foo FOR INSERT AS BEGIN SET NOCOUNT ON; INSERT dbo.Log(FooID) SELECT FooID FROM inserted; END GO
现在,您的情况是您想要一种可靠的方式来在插入后检索ID。SCOPE_IDENTITY()给您的是,因为它仅限于 您的范围 ,而@@IDENTITY不仅限于您的范围(这意味着它将捕获最后一个IDENTITY发出的事件,发生在触发器的范围内,而不是您的范围内:
INSERT dbo.Foo(name) SELECT 'Bob'; SELECT @@IDENTITY, SCOPE_IDENTITY();
结果:
---- ---- 100 1
请注意,在插入多行的情况下,都不应该使用SCOPE_IDENTITY()或@@IDENTITY。做到这一点的方法是使用该OUTPUT子句。首先让我们放下触发器:
OUTPUT
DROP TRIGGER dbo.Foo_Insert;
现在让我们测试一个多行插入:
INSERT dbo.Foo(name) OUTPUT inserted.FooID, inserted.name SELECT 'Frank' UNION ALL SELECT 'Jim';
FooID name ----- ----- 2 Frank 3 Jim
如果您有条件插入,则没有区别。保留我们拥有的表,让我们尝试两次此代码:
DECLARE @table SYSNAME; SET @table = N'Log'; IF @table = N'Log' BEGIN INSERT dbo.Log(FooID) SELECT 10; END IF @table = N'Foo' BEGIN INSERT dbo.Foo(name) SELECT 'Tom'; END SELECT SCOPE_IDENTITY();
---- 101
让我们再试一次N'Foo':
N'Foo'
DECLARE @table SYSNAME; SET @table = N'Foo'; IF @table = N'Log' BEGIN INSERT dbo.Log(FooID) SELECT 10; END IF @table = N'Foo' BEGIN INSERT dbo.Foo(name) SELECT 'Tom'; END SELECT SCOPE_IDENTITY();
---- 4
如果比这更复杂(例如,您可以插入多个表中),则可以执行以下操作:
IF <some conditional> BEGIN INSERT dbo.sometable ... SET @somevar = SCOPE_IDENTITY(); END IF <some other conditional> BEGIN INSERT dbo.some_other_table ... SET @some_other_var = SCOPE_IDENTITY(); END
我不确定您为什么认为这行不通,也不确定为什么我必须花这么长时间才能说服您这样做。同样,如果您显示了一个不起作用的示例(或者您认为可能干扰的“任何表”),我们也许可以发表评论。就目前而言,听起来您的意见SCOPE_IDENTITY()基于您所听说的内容@@IDENTITY。这些假设很容易证明或反驳自己。
顺便说一句,IDENT_CURRENT在此对话中甚至不应提及。完全不能将并发活动用于并发活动,并且您应该假装就我而言从未听说过它。您也应该考虑相同的问题@@IDENTITY-我无法想到它的有效用法,除非您确实确实想从触发器外部捕获触发器IDENTITY内部生成的内容。