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.
@@IDENTITY
le 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 1
puede darle resultados completamente incorrectos si la tabla tiene un paso de identidad negativo, o si ha insertado filas SET IDENTITY_INSERT
en 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.