Además del rendimiento, todos tienen significados bastante diferentes.
SCOPE_IDENTITY()le dará el último valor de identidad insertado en cualquier tabla directamente dentro del alcance actual (alcance = lote, procedimiento almacenado, etc. pero no dentro, por ejemplo, de un disparador que fue disparado por el alcance actual).
IDENT_CURRENT()le dará el último valor de identidad insertado en una tabla específica desde cualquier ámbito, por cualquier usuario.
@@IDENTITYle proporciona el último valor de identidad generado por la instrucción INSERT más reciente para la conexión actual, independientemente de la tabla o el alcance. (Nota al margen: Access usa esta función y, por lo tanto, tiene algunos problemas con los desencadenantes que insertan valores en tablas con columnas de identidad).
Usar MAX()o TOP 1puede darle resultados completamente incorrectos si la tabla tiene un paso de identidad negativo, o si ha insertado filas SET IDENTITY_INSERTen juego. Aquí hay un script que demuestra todo esto:
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
Resumen: palo con SCOPE_IDENTITY(), IDENT_CURRENT()o @@IDENTITY, y asegurarse de que está usando el que vuelve lo que realmente necesita.