Para um melhor entendimento vamos supor o seguinte exemplo:
Você possui duas tabelas T1,T2 e uma trigger de INSERT definida em T1.
Quando um registro é inserido na tabela T1, a trigger dispara e insere um registro na tabela T2. Este senário ilustra dois escopos: o insert em T1 e o insert em T2 como resultado do disparo da trigger.
Assumindo que T1 e T2 possuem coluna IDENTITY, @@IDENTITY e SCOPE_IDENTITY retornarão valores diferentes no final do INSERT sobre T1.
Script do exemplo:
USE tempdb
GO
CREATE TABLE T1 (
Z_id int IDENTITY(1,1)PRIMARY KEY,
Z_name varchar(20) NOT NULL)
INSERT T1
VALUES (‘Lisa’)
INSERT T1
VALUES (‘Mike’)
INSERT T1
VALUES (‘Carla’)
SELECT * FROM T1
— Registros em T1
Z_id Z_name
————-
1 Lisa
2 Mike
3 Carla
CREATE TABLE T2 (
Y_id int IDENTITY(100,5)PRIMARY KEY,
Y_name varchar(20) NULL)
INSERT T2 (Y_name)
VALUES (‘boathouse’)
INSERT T2 (Y_name)
VALUES (‘rocks’)
INSERT T2 (Y_name)
VALUES (‘elevator’)
SELECT * FROM T2
— Registros em T2
Y_id Y_name
—————
100 boathouse
105 rocks
110 elevator
/* Cria uma trigger que insere um registro em T2 quando um registro é inserido em T1 */
CREATE TRIGGER T1_trig
ON T1
FOR INSERT AS
BEGIN
INSERT T2 VALUES (”)
END
@@IDENTITY
Apesar de @@IDENTITY ser conhecido como uma variável global, ele é isolado por sessão, ou seja, retorna o último valor identity inserido em qualquer tabela desde que seja na sessão corrente. Entenda sessão como sendo uma conexão.
Exemplo:
/* Dispara a trigger e retorna o valor obtido para @@IDENTITY */
INSERT T1 VALUES (‘Rosalie’)
SELECT @@IDENTITY AS [@@IDENTITY] — Retorna 115 – valor identity inserido sobre a tabela T2
GO
O problema aqui é que a tabela T1 possui um trigger que também gera insert em outra tabela com identity (T2). O valor de @@IDENTITY é alterado devido ao insert realizado pelo trigger, desta forma o valor que será retornado não é o identity para T1, mas sim o identity para T2.
IDENT_CURRENT()
IDENT_CURRENT não é limitado por escopo ou sessão, mas sim por uma tabela em específico. IDENT_CURRENT retorna o último valor identity inserido em uma determinada tabela em qualquer sessão ou escopo.
Exemplo:
/* Dispara a trigger e retorna o valor obtido para IDENT_CURRENT */
INSERT T1 VALUES (‘Rosalie’)
SELECT IDENT_CURRENT(‘T1’) AS [IDENT_CURRENT] — Retorna 4 – valor identity inserido sobre a tabela T1
GO
Se estiver testando isso, irá parecer que funcionou, devolverá o valor identity para a tabela T1. O problema é que o IDENT_CURRENT não está preso a uma sessão, então se estiver ocorrendo inserções simultâneas sobre a tabela T1, o valor que ele poderá estar retornando pode não ser o da sua inserção.
SCOPE_IDENTITY()
Assim como @@IDENTITY, SCOPE_IDENTITY() retornará o último valor identity inserido em qualquer tabela na sessão corrente.
Exemplo:
/* Dispara a trigger e retorna o valor obtido para SCOPE_IDENTITY */
INSERT T1 VALUES (‘Rosalie’)
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY] — Retorna 4 – valor identity inserido sobre a tabela T1
GO
Entretando, SCOPE_IDENTITY é limitado a um escopo e com isso retornará o último valor identity inserido dentro do escopo de um determinado batch. Como o trigger é considerado um outro escopo, o valor de identity da tabela T1 será devolvido corretamente.
Para saber mais sobre @@Identity, ident_current() ou scope_identity(), consulte o Books Online do SQL Server 2000.

