No SQL Server, se você precisar retornar o valor criado em uma coluna de identidade, terá várias opções. Cada uma dessas opções, embora semelhantes, faz uma coisa ligeiramente diferente.
Em particular, você pode usar as seguintes funções:
IDENT_CURRENT()retorna o último valor de identidade inserido para uma determinada tabela.SCOPE_IDENTITY()retorna o último valor de identidade inserido em uma coluna de identidade em qualquer tabela na sessão atual e escopo atual.@@IDENTITYretorna o último valor de identidade inserido em qualquer tabela na sessão atual, independentemente do escopo.
Exemplo
Aqui está um exemplo que demonstra a diferença entre essas três funções.
Primeiro, crie duas tabelas. Observe os diferentes valores de semente e incremento sendo usados para a coluna de identidade em cada tabela:
CREATE TABLE t1(id int IDENTITY(1,1)); CREATE TABLE t2(id int IDENTITY(150,10));
Agora crie um gatilho que insira uma linha na segunda tabela sempre que uma linha for inserida na primeira tabela:
CREATE TRIGGER t1_insert_trigger ON t1 FOR INSERT AS BEGIN INSERT t2 DEFAULT VALUES END;
Os gatilhos disparam em um escopo diferente, então isso é perfeito para o meu exemplo aqui.
Insira dados na primeira tabela e selecione os resultados de ambas as tabelas:
INSERT t1 DEFAULT VALUES; SELECT id AS t1 FROM t1; SELECT id AS t2 FROM t2;
Resultado:
+------+ | t1 | |------| | 1 | +------+ (1 row affected) +------+ | t2 | |------| | 150 | +------+ (1 row affected)
Então, só para ficar claro, esses dados foram inseridos por dois escopos diferentes. A inserção em t1 foi feito pelo escopo atual. A inserção em t2 foi feito pelo gatilho, que foi executado em um escopo diferente.
Agora vamos selecionar entre as funções mencionadas anteriormente:
SELECT
@@IDENTITY AS [@@IDENTITY],
SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];
Resultado:
+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY | SCOPE_IDENTITY() | IDENT_CURRENT('t1') | IDENT_CURRENT('t2') |
|--------------+--------------------+-----------------------+-----------------------|
| 150 | 1 | 1 | 150 |
+--------------+--------------------+-----------------------+-----------------------+
O resultado retornado por
@@IDENTITY não está limitado ao escopo e, portanto, retorna o último valor de identidade inserido, independentemente do escopo. SCOPE_IDENTITY() retorna o valor de identidade da primeira tabela, porque esse foi o último valor de identidade inserido no escopo atual (o gatilho está fora do escopo atual). O
IDENT_CURRENT() A função simplesmente retorna o último valor de identidade inserido na tabela especificada, independentemente do escopo ou da sessão. Abrir uma nova sessão
Agora, aqui está o que acontece se eu abrir uma nova sessão e executar a instrução anterior novamente:
USE Test;
SELECT
@@IDENTITY AS [@@IDENTITY],
SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];
Resultado:
+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY | SCOPE_IDENTITY() | IDENT_CURRENT('t1') | IDENT_CURRENT('t2') |
|--------------+--------------------+-----------------------+-----------------------|
| NULL | NULL | 1 | 150 |
+--------------+--------------------+-----------------------+-----------------------+
Ambos
@@IDENTITY e SCOPE_IDENTITY() são NULL porque só retornam resultados da sessão atual. Eu não executei nenhuma inserção de coluna de identidade nesta nova sessão, então recebo NULL. IDENT_CURRENT() por outro lado, retorna o mesmo resultado do exemplo anterior, novamente porque seus resultados são baseados na tabela especificada, independente da sessão ou escopo.