¿Cuál es la mejor manera de obtener una IDENTITY
fila insertada?
Sé acerca de @@IDENTITY
y IDENT_CURRENT
y SCOPE_IDENTITY
pero no entiendo los pros y los contras asociados a cada uno.
¿Alguien puede explicar las diferencias y cuándo debería usarlas?
sql
sql-server
tsql
Oded
fuente
fuente
INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...)
, o un método anterior:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();
puede obtenerlo en C # usando ExecuteScalar ().OUTPUT
cláusula en SQL Server.Respuestas:
@@IDENTITY
devuelve el último valor de identidad generado para cualquier tabla en la sesión actual, en todos los ámbitos. Debe tener cuidado aquí , ya que está en todos los ámbitos. Podría obtener un valor de un activador, en lugar de su declaración actual.SCOPE_IDENTITY()
devuelve el último valor de identidad generado para cualquier tabla en la sesión actual y el alcance actual. Generalmente lo que quieres usar .IDENT_CURRENT('tableName')
devuelve el último valor de identidad generado para una tabla específica en cualquier sesión y cualquier ámbito. Esto le permite especificar de qué tabla desea el valor, en caso de que los dos anteriores no sean exactamente lo que necesita ( muy raro ). Además, como mencionó @ Guy Starbuck , "podría usar esto si desea obtener el valor de IDENTIDAD actual para una tabla en la que no ha insertado un registro".La
OUTPUT
cláusula de laINSERT
declaración le permitirá acceder a cada fila que se insertó a través de esa declaración. Dado que está enfocado a la declaración específica, es más sencillo que las otras funciones anteriores. Sin embargo, es un poco más detallado (necesitará insertar en una tabla variable / tabla temporal y luego consultar eso) y da resultados incluso en un escenario de error donde la declaración se revierte. Dicho esto, si su consulta usa un plan de ejecución en paralelo, este es el único método garantizado para obtener la identidad (salvo desactivar el paralelismo). Sin embargo, se ejecuta antes de los disparadores y no se puede usar para devolver valores generados por disparadores.fuente
output
usted no necesita crear una tabla temporal para almacenar y consultar los resultados. Simplemente omita lainto
parte de la cláusula de salida y los enviará a un conjunto de resultados.OUTPUT
es la "mejor" siempre y cuando no estés usando disparadores y estés manejando errores, peroSCOPE_IDENTITY
es el más simple y rara vez tiene problemasCreo que el método más seguro y preciso para recuperar la identificación insertada sería usar la cláusula de salida.
por ejemplo (tomado del siguiente artículo de MSDN )
fuente
OUTPUT
en SQL Server 2005 , por lo que parece que solo SQL Server 2000 yEstoy diciendo lo mismo que los otros chicos, así que todos están en lo correcto, solo estoy tratando de dejarlo más claro.
@@IDENTITY
devuelve la identificación de lo último que insertó la conexión de su cliente a la base de datos.La mayoría de las veces esto funciona bien, pero a veces se activará un disparador e insertará una nueva fila que desconoce, y obtendrá la ID de esta nueva fila, en lugar de la que desea
SCOPE_IDENTITY()
resuelve este problema Devuelve la identificación de lo último que insertó en el código SQL que envió a la base de datos. Si los disparadores van y crean filas adicionales, no harán que se devuelva el valor incorrecto. HurraIDENT_CURRENT
devuelve la última identificación que fue insertada por cualquiera. Si alguna otra aplicación inserta otra fila en un momento desafortunado, obtendrá la ID de esa fila en lugar de la suya.Si quieres jugar a lo seguro, úsalo siempre
SCOPE_IDENTITY()
. Si te quedas@@IDENTITY
y alguien decide agregar un disparador más adelante, todo tu código se romperá.fuente
La mejor manera (léase: la más segura) de obtener la identidad de una fila recién insertada es mediante la
output
cláusula:fuente
scope_identity()
) obtengan planes paralelos de todos modos. Y este error se solucionó más de un año antes de esta respuesta.output
lugar descope_identity()
. He eliminado el FUD sobre la agrupación en la respuesta.Añadir
hasta el final de su instrucción sql de inserción, luego
Lo recuperará.
fuente
Cuando usa Entity Framework, usa internamente la
OUTPUT
técnica para devolver el valor de ID recién insertadoLos resultados de salida se almacenan en una variable de tabla temporal, se unen de nuevo a la tabla y devuelven el valor de fila de la tabla.
Nota: No tengo idea de por qué EF uniría internamente la tabla efímera a la tabla real (en qué circunstancias los dos no coincidirían).
Pero eso es lo que hace EF.
Esta técnica (
OUTPUT
) solo está disponible en SQL Server 2008 o posterior.Editar : el motivo de la unión
La razón por la que Entity Framework se une a la tabla original, en lugar de simplemente usar los
OUTPUT
valores, es porque EF también usa esta técnica para obtener larowversion
fila recién insertada.Puede usar la concurrencia optimista en los modelos de marco de su entidad utilizando el
Timestamp
atributo: 🕗Cuando haga esto, Entity Framework necesitará
rowversion
la nueva fila insertada:Y para recuperar esto
Timetsamp
no puede usar unaOUTPUT
cláusula.Esto se debe a que si hay un disparador en la mesa, cualquier
Timestamp
salida que realice estará mal:La marca de tiempo devuelta nunca será correcta si tiene un activador en la tabla. Entonces debes usar un separado
SELECT
.E incluso si estuviera dispuesto a sufrir la versión incorrecta de la fila, la otra razón para realizar una separación
SELECT
es que no puede SALIR unarowversion
variable de tabla:La tercera razón para hacerlo es por simetría. Al realizar un
UPDATE
sobre una mesa con un disparador, no puede usar unaOUTPUT
cláusula. Intentar hacerUPDATE
con unOUTPUT
no es compatible, y dará un error:La única forma de hacerlo es con una
SELECT
declaración de seguimiento :fuente
TurboEncabulators
:)MSDN
fuente
@@ IDENTITY es la última identidad insertada utilizando la conexión SQL actual. Este es un buen valor para regresar de un procedimiento almacenado de inserción, donde solo necesita la identidad insertada para su nuevo registro, y no le importa si se agregaron más filas después.
SCOPE_IDENTITY es la última identidad insertada usando la conexión SQL actual, y en el alcance actual, es decir, si hubo una segunda IDENTIDAD insertada en función de un disparador después de su inserción, no se reflejaría en SCOPE_IDENTITY, solo la inserción que realizó . Francamente, nunca he tenido una razón para usar esto.
IDENT_CURRENT (nombre de tabla) es la última identidad insertada independientemente de la conexión o el alcance. Puede usar esto si desea obtener el valor de IDENTIDAD actual para una tabla en la que no ha insertado un registro.
fuente
No puedo hablar con otras versiones de SQL Server, pero en 2012, la salida directamente funciona bien. No necesita molestarse con una mesa temporal.
Por cierto, esta técnica también funciona al insertar varias filas.
Salida
fuente
OUTPUT
. Si no necesita la tabla temporal, su consulta termina siendo mucho más simple.SIEMPRE use scope_identity (), NUNCA hay necesidad de nada más.
fuente
Cree un
uuid
y también insértelo en una columna. Entonces puede identificar fácilmente su fila con el uuid. Esa es la única solución 100% funcional que puede implementar. Todas las demás soluciones son demasiado complicadas o no funcionan en los mismos casos extremos. P.ej:1) Crear fila
2) Obtener fila creada
fuente
uuid
en la base de datos. Entonces la fila se encontrará más rápido.https://www.npmjs.com/package/uuid
.const uuidv4 = require('uuid/v4'); const uuid = uuidv4()
Otra forma de garantizar la identidad de las filas que inserte es especificar los valores de identidad y usar el
SET IDENTITY_INSERT ON
y luegoOFF
. ¡Esto garantiza que sepa exactamente cuáles son los valores de identidad! Mientras los valores no estén en uso, puede insertar estos valores en la columna de identidad.Esta puede ser una técnica muy útil si está cargando datos de otra fuente o fusionando datos de dos bases de datos, etc.
fuente
Aunque este es un subproceso anterior, hay una forma más nueva de hacerlo que evita algunos de los escollos de la columna IDENTIDAD en las versiones anteriores de SQL Server, como las brechas en los valores de identidad después de reiniciar el servidor . Las secuencias están disponibles en SQL Server 2016 y el reenvío, que es la forma más nueva, es crear un objeto SECUENCIA usando TSQL. Esto le permite crear su propio objeto de secuencia numérica en SQL Server y controlar cómo se incrementa.
Aquí hay un ejemplo:
Luego, en TSQL, haría lo siguiente para obtener la siguiente ID de secuencia:
Aquí están los enlaces para CREAR SECUENCIA y SIGUIENTE VALOR PARA
fuente
Después de su declaración de inserción, debe agregar esto. Y asegúrese del nombre de la tabla donde se insertan los datos. Obtendrá la fila actual sin la fila afectada justo ahora por su instrucción de inserción.
fuente