2009-12-17 29 views
96

Scope_Identity(), Identity(), @@Identity, y Ident_Current() todos obtienen el valor de la columna de identidad, pero me gustaría saber la diferencia.¿Cuál es la diferencia entre Scope_Identity(), Identity(), @@ Identity e Ident_Current()?

Parte de la controversia que estoy teniendo es ¿qué significan por alcance como se aplica a estas funciones arriba?

También me gustaría un ejemplo simple de diferentes escenarios de uso de ellos?

+2

No se olvide del error de ejecución en paralelo que existe en SQL Server para SCOPE_IDENTITY y @@ IDENTIDAD: http://support.microsoft.com/default.aspx?scid=kb;en-US;2019779 –

+0

@DaviddCeFreitas - Tengo curiosidad por leer sobre el error, pero el enlace parece estar roto (o al menos, está arrojando un error ASP). –

+1

En realidad, lo encontré: https://support.microsoft.com/en-us/kb/2019779 –

Respuesta

218
  • La función @@identity devuelve la última identidad creada en la misma sesión.
  • La función devuelve el último scope_identity() identidad creada en la misma sesión y el mismo alcance.
  • El ident_current(name) devuelve la última identidad creada para una tabla o vista específica en cualquier sesión.
  • La función identity() no se utiliza para obtener una identidad, se utiliza para crear una identidad en una consulta select...into.

La sesión es la conexión de base de datos. El alcance es la consulta actual o el procedimiento almacenado actual.

Una situación donde las funciones scope_identity() y @@identity son diferentes, es si tiene un disparador sobre la mesa. Si usted tiene una consulta que inserta un registro, haciendo que el gatillo para insertar otro disco en alguna parte, la función scope_identity() devolverá la identidad creada por la consulta, mientras que la función @@identity devolverá la identidad creada por el gatillo.

Por lo tanto, normalmente se utilizaría la función scope_identity().

+5

+1 Muy explicativo. – Tebo

+9

Escogí esto como la respuesta, debido a la "situación en la que el scope_identity() y el @@ identity ..." párrafo. Aclaró las cosas más. – Tebo

+1

Como David Freitas mencionó anteriormente, hay un error en la implementación de scope_identity, por lo que recomiendo usar un método alternativo, la cláusula OUTPUT. Ver mi respuesta a continuación. –

34

Buena pregunta.

  • @@IDENTITY: devuelve el último valor de identidad generado en su conexión de SQL (SPID). La mayoría de las veces será lo que desee, pero a veces no lo es (como cuando se dispara un disparador en respuesta a un INSERT, y el desencadenador ejecuta otra instrucción INSERT).

  • SCOPE_IDENTITY(): devuelve el último valor de identidad generado en el ámbito actual (es decir, procedimiento almacenado, disparador, la función, etc).

  • IDENT_CURRENT(): devuelve el último valor de identidad para una tabla específica. No use esto para obtener el valor de identidad de INSERT, está sujeto a condiciones de carrera (es decir, conexiones múltiples que insertan filas en la misma tabla).

  • IDENTITY(): se utiliza al declarar una columna en una tabla como una columna de identidad.

Para obtener más información, ver: http://msdn.microsoft.com/en-us/library/ms187342.aspx.

En resumen: si está insertando filas, y que desea conocer el valor de la columna de identidad de la fila que acaba de insertar, siempre utilice SCOPE_IDENTITY().

+0

+1 Muy bien resumido – Kamal

+0

+1 para la explicación detallada. – Tebo

3

Scope Identity: Identidad del último registro agregado dentro del procedimiento almacenado que se está ejecutando.

@@Identity: Identidad del último registro agregado dentro del lote de consultas, o como resultado de la consulta, p. un procedimiento que realiza una inserción, luego dispara un disparador que luego inserta un registro devolverá la identidad del registro insertado desde el desencadenador.

IdentCurrent: La última identidad asignada para la tabla.

6

Para aclarar el problema con @@Identity:

Por ejemplo, si inserta una mesa y la mesa tiene disparadores haciendo inserciones, @@Identity devolverá el ID de la inserción en el gatillo (un algo log_id o), mientras scope_identity() devolverá la identificación de la inserción en la tabla original.

Así que si usted no tiene ningún activador, scope_identity() y @@identity devolverá el mismo valor. Si tiene factores desencadenantes, debe pensar qué valor le gustaría obtener.

10

Ámbito de aplicación significa el contexto del código que realiza la instrucción INSERTSCOPE_IDENTITY(), en comparación con el alcance global de @@IDENTITY.

CREATE TABLE Foo(
    ID INT IDENTITY(1,1), 
    Dummy VARCHAR(100) 
) 

CREATE TABLE FooLog(
    ID INT IDENTITY(2,2), 
    LogText VARCHAR(100) 
) 
go 
CREATE TRIGGER InsertFoo ON Foo AFTER INSERT AS 
BEGIN 
    INSERT INTO FooLog (LogText) VALUES ('inserted Foo') 
    INSERT INTO FooLog (LogText) SELECT Dummy FROM inserted 
END 

INSERT INTO Foo (Dummy) VALUES ('x') 
SELECT SCOPE_IDENTITY(), @@IDENTITY 

Da otros resultados.

+0

Gracias por el ejemplo. – Tebo

2

@@ identidad es una variable global que se utiliza para obtener el último identificador generado a nivel mundial. Mientras SCOPE_IDENTITY utilizado para conseguir la última ID generado en un ámbito de aplicación (procedimiento o función). Para obtener más información, consulte: - @@Identity is a globa variable used for to get the last generated id globally. While scope_identity used for to get the last generated id in a scope(procedure or function). For more detail see at :- http://interview-preparation-for-you.blogspot.com/2011/02/identity-and-scope-identity.html

11

Si comprende la diferencia entre el alcance y la sesión, será muy fácil comprender estos métodos.

Una muy agradable blog post por Adam Anderson describe esta diferencia:

Sesión significa la conexión actual que ha de ejecutar el comando.

Ámbito significa que el contexto inmediato de un comando. Cada llamada a procedimiento almacenado se ejecuta en su propio ámbito, y las llamadas anidadas se ejecutan en un ámbito anidado dentro del alcance del procedimiento de llamada. Del mismo modo, un comando SQL ejecutado desde una aplicación o SSMS se ejecuta en su propio ámbito, y si ese comando dispara cualquier activador, cada activador se ejecuta dentro de su propio alcance anidado.

Así, las diferencias entre los tres métodos de recuperación de identidad son los siguientes:

@@identity devuelve el último valor de identidad generado en esta sesión pero cualquier alcance.

scope_identity() devuelve el último valor de identidad generado en esta sesión y este ámbito.

ident_current() devuelve el último valor de identidad generado para una tabla en particular en cualquier sesión y cualquier ámbito.

6

Debido al error mencionado por @David Freitas y debido a la incompatibilidad con la nueva característica Sequence que se introdujo en 2012, recomendaría que se mantenga alejado de estos tres. En su lugar, puede usar la cláusula OUTPUT para obtener el valor de identidad insertado. La otra ventaja es que OUTPUT incluso funciona si ha insertado más de una fila.

Para más detalles y ejemplos ver aquí: Identity Crisis

3

Aquí es otra buena explicación de the book:

En cuanto a la diferencia entre SCOPE_IDENTITY y @@ IDENTITY, suponga que tiene un procedimiento almacenado con P1 tres instrucciones:
- Un INSERT que genera un nuevo valor de identidad
- Una llamada a un procedimiento almacenado P2 que también tiene una instrucción INSERT que genera un nuevo valor de identidad
- Una instrucción que consulta las funciones SCOPE_IDENTITY y @@ IDENTITY La función SCOPE_IDENTITY devolverá el valor generado por P1 (misma sesión y alcance). La función @@ IDENTITY devolverá el valor generado por P2 (misma sesión independientemente del alcance).

Cuestiones relacionadas