Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY no SQL Server:Qual é a diferença?


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.