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.@@IDENTITY
retorna 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.