A parte le prestazioni, hanno tutti significati piuttosto diversi.
SCOPE_IDENTITY()ti darà l'ultimo valore di identità inserito in qualsiasi tabella direttamente nell'ambito corrente (scope = batch, stored procedure, ecc. ma non all'interno, per esempio, di un trigger attivato dall'ambito corrente).
IDENT_CURRENT()ti darà l'ultimo valore di identità inserito in una tabella specifica da qualsiasi ambito, da qualsiasi utente.
@@IDENTITYfornisce l'ultimo valore di identità generato dall'istruzione INSERT più recente per la connessione corrente, indipendentemente dalla tabella o dall'ambito. (Nota a margine: Access utilizza questa funzione e quindi presenta alcuni problemi con i trigger che inseriscono valori in tabelle con colonne di identità.)
L'utilizzo MAX()o TOP 1può fornire risultati completamente errati se la tabella presenta un passaggio di identità negativo o se sono state inserite righe SET IDENTITY_INSERTin gioco. Ecco uno script che dimostra tutti questi:
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
Riassunto: bastone con SCOPE_IDENTITY(), IDENT_CURRENT()o @@IDENTITY, e assicurarsi che si sta utilizzando quella che restituisce quello che effettivamente bisogno.