当前会话的IDENT_CURRENT等价物

use*_*240 1 sql t-sql sql-server

我需要在特定的表中获取最后一个插入行以严格控制当前会话.我不能使用@@IDENTITY,SCOPE_IDENTITY()因为他们将返回任何表的最后插入的标识.问题IDENT_CURRENT是它将返回特定表的记录的最后插入标识,但是对于任何会话.这对我来说是一个问题,因为它INSERT是由多个会话调用的,我特别需要我的特定会话的最后插入记录的标识.

任何指针如何实现这一目标?

PS.该INSERT声明不在SPROC内部,因此SPROC解决方案不可行.

谢谢

Aar*_*and 6

我知道这不是你似乎想听到的答案,但答案是使用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
Run Code Online (Sandbox Code Playgroud)

现在,您的情况是您需要一种可靠的方法来在插入后检索ID.SCOPE_IDENTITY()为您提供,因为它仅限于您的范围,而@@IDENTITY不仅限于您的范围(意味着它将获取最后IDENTITY发布的,这发生在触发器的范围内,而不是您的范围:

INSERT dbo.Foo(name) SELECT 'Bob';

SELECT
  @@IDENTITY,
  SCOPE_IDENTITY();
Run Code Online (Sandbox Code Playgroud)

结果:

----  ----
100   1
Run Code Online (Sandbox Code Playgroud)

请注意,在插入多行的情况下既不应使用SCOPE_IDENTITY()也不@@IDENTITY应使用.这样做的方法是使用该OUTPUT子句.首先让我们放下触发器:

DROP TRIGGER dbo.Foo_Insert;
Run Code Online (Sandbox Code Playgroud)

现在让我们测试一个多行插入:

  INSERT dbo.Foo(name) 
    OUTPUT inserted.FooID, inserted.name
    SELECT 'Frank' UNION ALL SELECT 'Jim';
Run Code Online (Sandbox Code Playgroud)

结果:

FooID  name
-----  -----
2      Frank
3      Jim
Run Code Online (Sandbox Code Playgroud)

如果您有条件插入,则没有区别.保留我们的表格,让我们尝试两次代码:

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();
Run Code Online (Sandbox Code Playgroud)

结果:

----
101
Run Code Online (Sandbox Code Playgroud)

让我们再试一次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();
Run Code Online (Sandbox Code Playgroud)

结果:

----
4
Run Code Online (Sandbox Code Playgroud)

如果它比那更复杂(例如,您可以插入多个表),您可以执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

我不确定你为什么认为这不起作用,我不知道为什么我必须按照这个长度来说服你这样做.同样,如果您展示一个不起作用的示例(或您认为可能会干扰的"任何表格"),我们可能会发表评论.就目前而言,听起来您的意见SCOPE_IDENTITY()是基于您所听到的内容@@IDENTITY.这些假设很容易证明或反驳自己.

另外,IDENT_CURRENT在这次谈话中甚至不应该提到.根本不能安全地用于并发活动,你应该假装你从未听说过我所关心的事情.你也应该考虑相同的@@IDENTITY- 我想不出它的有效用途,除非你真的想从触发器外部捕获IDENTITY生成的触发器内部.