sql >> Base de Datos >  >> RDS >> Sqlserver

Utilice SCOPE_IDENTITY() para devolver el último valor de identidad insertado en el mismo ámbito (SQL Server)

En SQL Server, puede usar T-SQL SCOPE_IDENTITY() función para devolver el último valor de identidad insertado en una columna de identidad en el mismo ámbito.

Un ámbito es un módulo (procedimiento almacenado, activador, función o lote). Si dos declaraciones están en el mismo procedimiento almacenado, función o lote, están en el mismo ámbito.

Tenga en cuenta que devuelve el último valor de identidad generado en cualquier tabla en la sesión actual . Esto contrasta con IDENT_CURRENT() función, que devuelve el último valor de identidad insertado para una tabla determinada , independientemente de la sesión en la que se encuentre.

SCOPE_IDENTITY() es muy similar a @@IDENTITY en el sentido de que ambos devuelven el último valor de identidad insertado en la sesión actual. La diferencia es que SCOPE_IDENTITY() se limita al ámbito actual, mientras que @@IDENTITY no se limita a un ámbito específico.

Ejemplo 1:uso básico

Aquí hay un ejemplo de código básico de cómo funciona.

SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultado:

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

El motivo del resultado NULL es que ejecuté la declaración inmediatamente después de abrir una nueva conexión a SQL Server. El SCOPE_IDENTITY() La función solo devuelve los resultados de la sesión actual.

Entonces, para obtener un resultado que no sea NULL, necesito insertar un valor en una columna de identidad.

Ejemplo 2:Insertar un valor para un resultado no NULL

En este ejemplo, creo una tabla con una columna de identidad. Luego inserto un valor predeterminado en esa tabla antes de seleccionar el contenido de la tabla y luego ejecutar SCOPE_IDENTITY() de nuevo.

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)

La tabla tiene una fila y su columna de identidad tiene un valor de 1. Este es el último valor de identidad insertado para la sesión actual, por lo que SCOPE_IDENTITY() también devuelve 1.

Ahora, si agrego otra fila, el valor aumenta en consecuencia:

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 una nueva sesión

Como se mencionó, SCOPE_IDENTITY() solo devuelve resultados de la misma sesión. Esto también es cierto para @@IDENTITY .

Entonces, si abro una nueva conexión a SQL Server y ejecuto el anterior SELECT declaraciones de nuevo, obtengo los siguientes 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)

Ahora insertemos una nueva fila dentro de esta nueva sesión:

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)

Entonces se puso al día tan pronto como inserté un nuevo valor de identidad.

Sin embargo, volvamos a la sesión original y ejecutemos SELECT declaraciones de nuevo (sin insertar una nueva fila):

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)

Así que el SCOPE_IDENTITY() de la sesión original los resultados no se han visto afectados por la segunda sesión.

Agregar un segundo alcance

Lo que diferencia SCOPE_IDENTITY() de @@IDENTITY , es que SCOPE_IDENTITY() se limita al alcance actual.

Por ejemplo, si la tabla tiene un activador que inserta un valor de identidad en otra tabla, SCOPE_IDENTITY() solo reportaría el primer valor de identidad. Ignoraría el valor de identidad para la segunda tabla, porque se creó en un ámbito diferente @@IDENTITY por otro lado, reportaría el valor de identidad para la segunda tabla (porque cubre todos los ámbitos).

Para ver un ejemplo de lo que quiero decir, consulte IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY en SQL Server:¿Cuál es la diferencia?

Ese artículo recorre un ejemplo de disparador como el que estoy hablando aquí.