529 votos

¿Mejor manera de obtener la identidad de fila insertada?

¿Cuál es la mejor manera de obtener la identidad de la fila insertada.

Sé sobre @@IDENTITY y IDENT_CURRENT y SCOPE_IDENTITY pero no entiendo los pros y contras adjunta a cada uno.

¿Puede alguien explicarme las diferencias y cuando debería estar usando cada uno?

680voto

bdukes Puntos 54833
  • @@IDENTITY devuelve el último valor de identidad generado por cualquier tabla en la sesión actual, en todos los ámbitos. Usted necesita tener cuidado aquí, ya que es a través de los ámbitos. Usted podría obtener un valor de un disparo, en lugar de su estado de cuenta actual.
  • SCOPE_IDENTITY devuelve el último valor de identidad generado por cualquier tabla en la sesión actual y el alcance de las actuales. En general lo que usted desea utilizar.
  • IDENT_CURRENT devuelve el último valor de identidad generado para una tabla específica en cualquiera de las sesiones y en cualquier ámbito. Esto le permite especificar la tabla que desea que el valor de, en caso de que los dos de arriba no son exactamente lo que usted necesita (muy raro). También, como @Guy Starbuck mencionado, "Se podría usar si usted desea obtener el valor de IDENTIDAD actual de una tabla que no ha insertado un registro".
  • La OUTPUT cláusula de la INSERT declaración te permitirá acceder a cada fila que se inserta a través de esa declaración. Ya que es en el ámbito de la declaración específica, es más sencillo que el de otras funciones anteriores. Sin embargo, es un poco más detallado (el que tendrás que insertar en una variable de tabla/tabla temporal y, a continuación, consulta) y da resultados incluso en un escenario de error cuando la declaración se revierte. Dicho esto, si la consulta utiliza un plan de ejecución en paralelo, este es el único método garantizado para la obtención de la identidad (corto de apagar el paralelismo). Sin embargo, se ejecuta antes de que se desencadena y no puede ser usada para regresar a desencadenar los valores generados.

82voto

Orry Puntos 659

Yo creo que el método más seguro y más exacto de recuperar el id insertado estaría utilizando la cláusula de salida.

por ejemplo (tomado del siguiente artículo MSDN )

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

56voto

Orion Edwards Puntos 54939

Yo estoy diciendo lo mismo que los otros chicos, así que todo el mundo está en lo correcto, yo solo estoy tratando de hacerla más clara.

@@IDENTITY devuelve el identificador de la última cosa que fue insertado por su conexión del cliente a la base de datos.
La mayoría de las veces esto funciona bien, pero a veces un desencadenador se vaya y se inserta una nueva fila que usted no lo sepa, y usted va a obtener el ID de esta nueva fila, en lugar de la que desea

SCOPE_IDENTITY() resuelve este problema. Devuelve el id de la última cosa que usted inserta en el código SQL que envió a la base de datos. Si los desencadenadores ir y crear más filas, no van a causar el valor incorrecto para obtener devueltos. ¡Hurra

IDENT_CURRENT devuelve el último ID que fue insertado por nadie. Si alguna otra aplicación que sucede para insertar otra fila en una unforunate el tiempo, usted obtendrá el ID de la fila en lugar de la una.

Si quieres jugar a lo seguro, siempre uso SCOPE_IDENTITY(). Si usted se pega con @@IDENTITY y alguien decide agregar un desencadenador más tarde, todo el código se va a romper.

23voto

Ian Kemp Puntos 6408

Los mejores (Lea: más seguro) manera de obtener la identidad de una fila recién insertado es mediante el uso de la output cláusula. Cualquier otro método no está garantizado que devuelve el ID correcto cuando se utiliza el paralelismo - incluso si no está utilizando paralelismo ahora, escribiendo tu SQL como esto le asegurará no tienen que cambiarlo debe pasar a un entorno en paralelo (e.g. clúster de servidores SQL).

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

5voto

erikkallen Puntos 16601

Utilice siempre scope_identity(), nunca hay una necesidad para cualquier otra cosa.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: