Подтвердить что ты не робот

@@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 in the Wild

4b9b3361

Ответ 1

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

@@IDENTITY

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

SCOPE_IDENTITY()

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

IDENT_CURRENT()

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

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

Ответ 7

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

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

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