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

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY en SQL Server:¿Cuál es la diferencia?

En SQL Server, si alguna vez necesita devolver el valor creado en una columna de identidad, tiene varias opciones. Cada una de estas opciones, aunque similares, hacen algo ligeramente diferente.

En particular, puede utilizar las siguientes funciones:

  • IDENT_CURRENT() devuelve el último valor de identidad insertado para una tabla dada.
  • SCOPE_IDENTITY() devuelve el último valor de identidad insertado en una columna de identidad en any tabla en la sesión actual y el ámbito actual.
  • @@IDENTITY devuelve el último valor de identidad insertado en any tabla en la sesión actual, independientemente del ámbito.

Ejemplo

Aquí hay un ejemplo que demuestra la diferencia entre estas tres funciones.

Primero, crea dos tablas. Observe los diferentes valores iniciales y de incremento que se utilizan para la columna de identidad en cada tabla:

CREATE TABLE t1(id int IDENTITY(1,1));  
CREATE TABLE t2(id int IDENTITY(150,10));

Ahora cree un activador que inserte una fila en la segunda tabla siempre que se inserte una fila en la primera tabla:

CREATE TRIGGER t1_insert_trigger ON t1 FOR INSERT
AS
BEGIN
  INSERT t2 DEFAULT VALUES
END;

Los disparadores se disparan en un alcance diferente, por lo que es perfecto para mi ejemplo aquí.

Inserte datos en la primera tabla, luego seleccione los resultados de ambas tablas:

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)

Entonces, para que quede claro, estos datos fueron insertados por dos ámbitos diferentes. La inserción en t1 fue hecho por el alcance actual. La inserción en t2 fue realizado por el activador, que se ejecutó en un ámbito diferente.

Ahora seleccionemos entre las funciones 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                   |
+--------------+--------------------+-----------------------+-----------------------+

El resultado devuelto por @@IDENTITY no se limita al ámbito y, por lo tanto, devuelve el último valor de identidad insertado, independientemente del ámbito.

SCOPE_IDENTITY() devuelve el valor de identidad de la primera tabla, porque ese fue el último valor de identidad insertado dentro del ámbito actual (el disparador está fuera del ámbito actual).

El IDENT_CURRENT() La función simplemente devuelve el último valor de identidad insertado en la tabla especificada, independientemente del ámbito o la sesión.

Abrir una nueva sesión

Ahora, esto es lo que sucede si abro una nueva sesión y vuelvo a ejecutar la instrucción anterior:

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 y SCOPE_IDENTITY() son NULL porque solo devuelven resultados de la sesión actual. No he realizado ninguna inserción de columna de identidad en esta nueva sesión, por lo que obtengo NULL.

IDENT_CURRENT() por otro lado, devuelve el mismo resultado que en el ejemplo anterior, nuevamente porque sus resultados se basan en la tabla especificada, independientemente de la sesión o el ámbito.