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

Use SCOPE_IDENTITY() para retornar o último valor de identidade inserido no mesmo escopo (SQL Server)


No SQL Server, você pode usar o T-SQL SCOPE_IDENTITY() função para retornar o último valor de identidade inserido em uma coluna de identidade no mesmo escopo.

Um escopo é um módulo (procedimento armazenado, gatilho, função ou lote). Se duas instruções estiverem no mesmo procedimento armazenado, função ou lote, elas estarão no mesmo escopo.

Observe que ele retorna o último valor de identidade gerado em qualquer tabela na sessão atual . Isso contrasta com o IDENT_CURRENT() função, que retorna o último valor de identidade inserido para uma determinada tabela , independentemente da sessão em que está.

SCOPE_IDENTITY() é muito semelhante a @@IDENTITY em que ambos retornam o último valor de identidade inserido na sessão atual. A diferença é que SCOPE_IDENTITY() é limitado ao escopo atual, enquanto @@IDENTITY não se limita a um escopo específico.


Exemplo 1 – Uso básico


Aqui está um exemplo de código básico de como funciona.
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+

O motivo do resultado NULL é porque executei a instrução imediatamente após abrir uma nova conexão com o SQL Server. O SCOPE_IDENTITY() A função retorna apenas os resultados da sessão atual.

Portanto, para obter um resultado não NULL, preciso inserir um valor em uma coluna de identidade.

Exemplo 2 – Inserir um valor para um resultado não nulo


Neste exemplo, crio uma tabela com uma coluna de identidade. Em seguida, insiro um valor padrão nessa tabela antes de selecionar o conteúdo da tabela e, em seguida, executar SCOPE_IDENTITY() novamente.
CREATE TABLE scope_identity_test(id int IDENTITY(1,1));
INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+------+
| id   |
|------|
| 1    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 1                              |
+--------------------------------+
(1 row affected)

A tabela tem uma linha e sua coluna de identidade tem um valor de 1. Este é o último valor de identidade inserido para a sessão atual e, portanto, SCOPE_IDENTITY() também retorna 1.

Agora, se eu adicionar outra linha, o valor será incrementado de acordo:
INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Resultados de uma nova sessão


Como mencionado, SCOPE_IDENTITY() apenas retorna resultados da mesma sessão. Isso também vale para @@IDENTITY .

Então, se eu abrir uma nova conexão com o SQL Server e executar o SELECT anterior declarações novamente, recebo os seguintes resultados:
USE Test;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+
(1 row affected)

Agora vamos inserir uma nova linha dentro desta nova sessão:
INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 3                              |
+--------------------------------+
(3 rows affected)

Então ele pegou assim que eu inseri um novo valor de identidade.

No entanto, vamos voltar para a sessão original e executar o SELECT instruções novamente (sem inserir uma nova linha):
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:
+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(3 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Portanto, o SCOPE_IDENTITY() da sessão original os resultados não foram afetados pela segunda sessão.

Adicionando um segundo escopo


O que diferencia SCOPE_IDENTITY() de @@IDENTITY , isso é SCOPE_IDENTITY() está limitado ao escopo atual.

Por exemplo, se a tabela tiver um gatilho que insere um valor de identidade em outra tabela, SCOPE_IDENTITY() reportaria apenas o primeiro valor de identidade. Ignoraria o valor de identidade para a segunda tabela, porque ela foi criada em um escopo diferente @@IDENTITY por outro lado, reportaria o valor de identidade para a segunda tabela (porque abrange todos os escopos).

Para obter um exemplo do que quero dizer, consulte IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY no SQL Server:Qual é a diferença?

Esse artigo percorre um exemplo de gatilho como o que estou falando aqui.