@@IDENTITY, SCOPE_IDENTITY(), OUTPUT и другие методы получения последней идентичности

Я видел различные методы, используемые при получении значения поля идентификатора первичного ключа после вставки.

declare @t table (
    id int identity primary key,
    somecol datetime default getdate()
)
insert into @t
default values

select SCOPE_IDENTITY() --returns 1
select @@IDENTITY --returns 1

Возвращаем таблицу тождеств после следующей вставки:

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values   

Какой метод подходит или лучше? Является ли метод OUTPUT безопасным для объема?

Второй фрагмент кода был заимствован из SQL в Wild

8 ответов

Это зависит от того, что вы пытаетесь сделать...

@@ IDENTITY

Возвращает последнее значение IDENTITY, созданное для соединения, независимо от таблицы, которая произвела значение, и независимо от области действия оператора, который произвел значение. @@IDENTITY вернет последнее значение идентификатора, введенное в таблицу в текущем сеансе. @@IDENTITY ограничен текущим сеансом и не ограничен текущей областью действия. Например, если у вас есть триггер в таблице, который вызывает создание идентификатора в другой таблице, вы получите идентификатор, который был создан последним, даже если это был триггер, который его создал.

SCOPE_IDENTITY ()

Возвращает последнее значение IDENTITY, созданное для соединения и оператора в той же области, независимо от таблицы, которая произвела значение. SCOPE_IDENTITY() похож на @@IDENTITY, но он также ограничит значение вашей текущей областью действия. Другими словами, он вернет последнее значение идентификатора, которое вы явно создали, а не любое идентификатор, созданный триггером или определенной пользователем функцией.

IDENT_CURRENT ()

Возвращает последнее значение IDENTITY, созданное в таблице, независимо от соединения и области действия оператора, создавшего значение. IDENT_CURRENT ограничен указанной таблицей, но не подключением или областью действия.

Обратите внимание, что существует ошибка в scope_identity() и @@identity - см. Connect: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

Цитата (от Microsoft):

"Я настоятельно рекомендую использовать OUTPUT вместо @@IDENTITY во всех случаях. Это просто лучший способ прочитать личность и метку времени".

Отредактировано, чтобы добавить: это может быть исправлено сейчас, Connect дает мне ошибку, но смотрите:

Scope_Identity () возвращает неправильное значение исправлено?

Почти нет причин использовать что-либо кроме OUTPUT предложение при попытке получить идентификатор вставленной строки (строк). Предложение OUTPUT является безопасным для области и таблицы.

Вот простой пример получения идентификатора после вставки одной строки...

DECLARE @Inserted AS TABLE (MyTableId INT);

INSERT [MyTable] (MyTableColOne, MyTableColTwo)
OUTPUT Inserted.MyTableId INTO @Inserted
VALUES ('Val1','Val2')

SELECT MyTableId FROM @Inserted

Подробные документы для предложения OUTPUT: http://technet.microsoft.com/en-us/library/ms177564.aspx


-- table structure for example:     
CREATE TABLE MyTable (
    MyTableId int NOT NULL IDENTITY (1, 1),
    MyTableColOne varchar(50) NOT NULL,
    MyTableColTwo varchar(50) NOT NULL
)

@@ Идентичность - это старая школа. Используйте SCOPE_IDENTITY() во всех случаях вперед. См. MSDN о последствиях использования @@IDENTITY (они плохие!).

SCOPE_IDENTITY достаточно для отдельных строк и рекомендуется, за исключением случаев, когда вам необходимо по какой-либо причине увидеть результат промежуточного TRIGGER (почему?).

Для нескольких строк OUTPUT/OUTPUT INTO - ваш новый лучший друг и альтернатива повторному поиску строк и вставке в другую таблицу.

В SQL Server 2005 есть еще один метод, который описан в SQL в Wild.

Это позволит вам получить несколько идентификаторов после вставки. Вот код из поста в блоге:

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values

Небольшая поправка к ответу Годеке:

Вам нужно беспокоиться не только о триггерах. Любые вложенные операции, такие как хранимые процедуры, которые вызывают создание идентификаторов, могут изменить значение @@IDENTITY.

Еще один голос за scope_identity...

Будьте осторожны при использовании @@ IDENTITY...

http://dotnetgalactics.wordpress.com/2009/10/28/scope-identity-vs-identity/

Другие вопросы по тегам