Além do desempenho, todos eles têm significados bastante diferentes.
SCOPE_IDENTITY()
fornecerá o último valor de identidade inserido em qualquer tabela diretamente dentro do escopo atual (escopo = lote, procedimento armazenado, etc., mas não dentro, por exemplo, de um gatilho que foi disparado pelo escopo atual).
IDENT_CURRENT()
fornecerá o último valor de identidade inserido em uma tabela específica de qualquer escopo, por qualquer usuário.
@@IDENTITY
fornece o último valor de identidade gerado pela instrução INSERT mais recente para a conexão atual, independentemente da tabela ou escopo. (Observação: o Access usa essa função e, portanto, tem alguns problemas com gatilhos que inserem valores em tabelas com colunas de identidade.)
Usar MAX()
ou TOP 1
pode fornecer resultados totalmente errados se a tabela tiver uma etapa de identidade negativa ou se houver linhas inseridas SET IDENTITY_INSERT
em execução. Aqui está um script demonstrando tudo isso:
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
Resumo: vara com SCOPE_IDENTITY()
, IDENT_CURRENT()
ou @@IDENTITY
, e certifique-se que você está usando o que retorna o que você realmente precisa.