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.
@@IDENTITY
fornisce 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 1
può fornire risultati completamente errati se la tabella presenta un passaggio di identità negativo o se sono state inserite righe SET IDENTITY_INSERT
in 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.