@@ IDENTITY, SCOPE_IDENTITY (), OUTPUT и другие методы получения последней личности - PullRequest
56 голосов
/ 27 января 2009

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

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 ]

70 голосов
/ 27 января 2009

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

@@ IDENTITY

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

SCOPE_IDENTITY ()

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

IDENT_CURRENT ()

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

12 голосов
/ 15 сентября 2009

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

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

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

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

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

8 голосов
/ 08 декабря 2014

Почти нет причин использовать что-либо, кроме предложения 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
)
6 голосов
/ 27 января 2009

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

3 голосов
/ 27 января 2009

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

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

3 голосов
/ 27 января 2009

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

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

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

3 голосов
/ 27 января 2009

В SQL Server 2005 доступен еще один метод, который обозначен в SQL в Wild: .

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

Create Table #Testing (  
    id int identity,  
    somedate datetime default getdate()  
)  
insert into #Testing  
output inserted.*  
default values
1 голос
/ 02 ноября 2009

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

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

...