@@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/