2012-07-01 3 views
1

Мне нужно получить последнюю вставленную строку в определенной таблице для строго текущей сессии. Я не могу использовать @@IDENTITY и SCOPE_IDENTITY(), так как они возвратят последний вставленный идентификатор для ЛЮБОЙ таблицы. Проблема с IDENT_CURRENT заключается в том, что она вернет последний вставленный идентификатор записи для конкретной таблицы, но для ЛЮБОГО сеанса. Это проблема для меня, потому что INSERT вызывается несколькими сеансами, и мне определенно нужна личность последней вставленной записи для моего конкретного сеанса.Идентификатор IDENT_CURRENT для текущего сеанса

Любые указатели, как это сделать?

пс. оператор INSERT не находится внутри SPROC, поэтому решения SPROC не являются жизнеспособными.

Благодаря

+3

В какой ситуации SCOPE_IDENTITY() не работает? Можете ли вы продемонстрировать пример? IDENT_CURRENT - это не способ сделать это. –

+0

Что именно нужно ID? Не могли бы вы немного разобраться в архитектуре, с которой работаете? Вы пытаетесь захватить значение идентификатора, вставленное в таблицу, отличную от той, на которую ссылается ваш запрос? –

+0

Как я уже сказал, SCOPE_IDENTITY возвращает личность последней записи, вставленной для ЛЮБОЙ таблицы .................... – user577240

ответ

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 

Теперь ваша ситуация в том, что вы хотите надежный способ получить идентификатор после вставки. 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, сгенерированный внутри триггера.

+1

Чтобы ответить на ваш вопрос, вы вошли в эту длину, чтобы убедить меня в том, что вы увлечены и ваш полезный добрый человек. Извините, я заставил вас сделать это, чтобы доказать ваше решение. Благодарю вас и высоко ценим. – user577240

+1

@ user577240 Ну, я попробовал несколько раз объяснить несколько комментариев с комментариями, которые SCOPE_IDENTITY() не срабатывает, как вы думаете, но у вас его не было. –

+1

@ user577240: вам повезло - Аарон (а) действительно хорошо разбирается в таких вещах, (b) как вы говорите: очень увлечен своими темами, и (в) просто очень полезно. –