对于当前会话,我需要获取特定表中最后插入的行。我不能使用@@IDENTITY
,SCOPE_IDENTITY()
因为它们将返回任何表的最后插入的标识。问题IDENT_CURRENT
在于它将返回特定表的最后插入的记录标识,但对于任何会话。这对我来说是个问题,因为INSERT
它被多个会话调用,并且我特别需要我的特定会话的最后插入记录的标识。
任何指针如何做到这一点?
附言。该INSERT
语句不在 SPROC 内,因此 SPROC 解决方案不可行。
谢谢
对于当前会话,我需要获取特定表中最后插入的行。我不能使用@@IDENTITY
,SCOPE_IDENTITY()
因为它们将返回任何表的最后插入的标识。问题IDENT_CURRENT
在于它将返回特定表的最后插入的记录标识,但对于任何会话。这对我来说是个问题,因为INSERT
它被多个会话调用,并且我特别需要我的特定会话的最后插入记录的标识。
任何指针如何做到这一点?
附言。该INSERT
语句不在 SPROC 内,因此 SPROC 解决方案不可行。
谢谢
我知道这不是您似乎想听到的答案,但答案是使用SCOPE_IDENTITY()
. 您正在考虑的问题(任何表格都将在哪里)是我们使用SCOPE_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
子句。首先让我们放下触发器:
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'
:
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
内部生成的内容。