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