Помимо производительности, все они имеют довольно разные значения.
SCOPE_IDENTITY()
даст вам последнее значение идентификатора, вставленное в любую таблицу непосредственно в текущей области (область = пакет, хранимая процедура и т. д., но не в пределах, скажем, триггера, который был запущен текущей областью).
IDENT_CURRENT()
даст вам последнее значение идентификатора, вставленное в определенную таблицу из любой области, любым пользователем.
@@IDENTITY
дает вам последнее значение идентификатора, сгенерированное самым последним оператором INSERT для текущего соединения, независимо от таблицы или области. (Примечание: Access использует эту функцию и поэтому имеет некоторые проблемы с триггерами, которые вставляют значения в таблицы со столбцами идентификаторов.)
Использование MAX()
или TOP 1
может дать вам совершенно неверные результаты, если таблица имеет шаг отрицательной идентификации или в нее вставлены строки SET IDENTITY_INSERT
. Вот скрипт, демонстрирующий все это:
CREATE TABLE ReverseIdent (
id int IDENTITY(9000,-1) NOT NULL PRIMARY KEY CLUSTERED,
data char(4)
)
INSERT INTO ReverseIdent (data)
VALUES ('a'), ('b'), ('c')
SELECT * FROM ReverseIdent
SELECT IDENT_CURRENT('ReverseIdent') --8998
SELECT MAX(id) FROM ReverseIdent --9000
SET IDENTITY_INSERT ReverseIdent ON
INSERT INTO ReverseIdent (id, data)
VALUES (9005, 'd')
SET IDENTITY_INSERT ReverseIdent OFF
SELECT IDENT_CURRENT('ReverseIdent') --8998
SELECT MAX(id) FROM ReverseIdent --9005
Резюме: палка SCOPE_IDENTITY()
, IDENT_CURRENT()
или @@IDENTITY
, и убедитесь , что вы используете тот , который возвращает то , что вы на самом деле нужно.