scope_identity last inserted ident_current funcion example and sql sql-server tsql

sql - last - scope_identity vs ident_current



sql server difference between @@ identity scope_identity() and ident_current (6)

Después de mucha investigación, estoy un poco confundido por el rastreador de identidad que debería usar en SQL.

Por lo que entiendo, scope_identity me dará la última identificación actualizada de cualquier tabla e ident_current devolverá la última identificación de una tabla especificada.

Entonces, dada esa información, me parece que la mejor versión para usar (si sabes en qué tabla estarás actualizando) es ident_current. Sin embargo, al leer, parece que la mayoría de la gente prefiere usar scope_identity. ¿Cuál es el razonamiento detrás de esto y hay un defecto en mi lógica?


En ese caso, debe escribir el nombre de la tabla, ¿qué sucede si decide cambiar el nombre de la tabla? Entonces tampoco debe olvidarse de actualizar su código para reflejar eso. Siempre uso SCOPE_IDENTITY a menos que necesite el ID del inserto que ocurre en un desencadenante, entonces usaré @@ IDENTITY

También la diferencia más grande es que IDENT_CURRENT le dará la identidad de otro proceso que hizo la inserción (en otras palabras, el último valor de identidad generado de cualquier usuario) así que si hace una inserción y luego alguien hace una inserción antes de hacer un SELECT IDENT_CURRENT usted obtendrá el valor de identidad de esa otra persona

Ver también 6 formas diferentes de obtener el valor de identidad actual que tiene algún código que explica lo que sucede cuando se ponen los factores desencadenantes en la mesa


Vea este blogpost para su respuesta en detalle. Scope_identity nunca devolverá identidades debido a inserciones realizadas por desencadenantes. No será una buena idea usar ident_current en un mundo de cambios donde los nombres de las tablas cambian ... como en un env env.


Por lo que he leído, scope_identity () debería ser la respuesta correcta, sin embargo, parece que hay un error en SQL 2005 y SQL 2008 que puede entrar en juego si su inserción da como resultado un plan de consulta paralelo.

Eche un vistazo a los siguientes artículos para más detalles:

@@IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT - Recuperar la última identidad de registro insertada

atajo: http://tinyurl.com/4vbhju

(http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/)

Artículo: Seis razones por las que deberías estar nervioso por el paralelismo

Consulte la sección titulada: 1. # 328811, " SCOPE_IDENTITY() veces devuelve un valor incorrecto"

atajo: http://tinyurl.com/krm3q4

( http://sqlblog.com/blogs/aaron_bertrand/archive/2009/03/21/six-reasons-you-should-be-nervous-about-parallelism.aspx )


/* * IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope. * @@IDENTITY returns the last identity value generated for any table in the current session, across all scopes. * SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope. */ IF OBJECT_ID(N''t6'', N''U'') IS NOT NULL DROP TABLE t6 ; GO IF OBJECT_ID(N''t7'', N''U'') IS NOT NULL DROP TABLE t7 ; GO CREATE TABLE t6 (id INT IDENTITY) ; CREATE TABLE t7 ( id INT IDENTITY(100, 1) ) ; GO CREATE TRIGGER t6ins ON t6 FOR INSERT AS BEGIN INSERT t7 DEFAULT VALUES END ; GO --End of trigger definition SELECT id FROM t6 ; --IDs empty. SELECT id FROM t7 ; --ID is empty. --Do the following in Session 1 INSERT t6 DEFAULT VALUES ; SELECT @@IDENTITY ; /*Returns the value 100. This was inserted by the trigger.*/ SELECT SCOPE_IDENTITY() ; /* Returns the value 1. This was inserted by the INSERT statement two statements before this query.*/ SELECT IDENT_CURRENT(''t7'') ; /* Returns 100, the value inserted into t7, that is in the trigger.*/ SELECT IDENT_CURRENT(''t6'') ; /* Returns 1, the value inserted into t6 four statements before this query.*/ -- Do the following in Session 2. SELECT @@IDENTITY ; /* Returns NULL because there has been no INSERT action up to this point in this session.*/ SELECT SCOPE_IDENTITY() ; /* Returns NULL because there has been no INSERT action up to this point in this scope in this session.*/ SELECT IDENT_CURRENT(''t7'') ; /* Returns 100, the last value inserted into t7.*/


La teoría dice: para estar al tanto de las condiciones de carrera y para que no te preocupen las inserciones dentro de los desencadenantes, debes usar SCOPE_IDENTITY() PERO ... hay errores conocidos en SCOPE_IDENTITY () (y @@ IDENTITY) como se menciona y está vinculado en otros artículos. Aquí están las soluciones provisionales de Microsoft que tienen en cuenta estos errores.

Debajo de la parte más relevante del artículo. Utiliza la cláusula de inserción de output :

DECLARE @MyNewIdentityValues table(myidvalues int) declare @A table (ID int primary key) insert into @A values (1) declare @B table (ID int primary key identity(1,1), B int not null) insert into @B values (1) select [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY() set statistics profile on insert into _ddr_T output inserted.ID into @MyNewIdentityValues select b.ID from @A a left join @B b on b.ID = 1 left join @B b2 on b2.B = -1 left join _ddr_T t on t.T = -1 where not exists (select * from _ddr_T t2 where t2.ID = -1) set statistics profile off select [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY(), [IDENT_CURRENT] = IDENT_CURRENT(''_ddr_T'') select * from @MyNewIdentityValues go


SELECT IDENT_CURRENT : como dijo, le dará el último valor de identidad insertado específico de la tabla. Hay problemas asociados con esto, uno el usuario necesita tener permiso para ver los metadatos, de lo contrario, devuelve NULL y en segundo lugar está codificando el nombre de la tabla, lo que causará un problema en caso de que cambie el nombre de la tabla.

La mejor práctica es usar Scope_Identity junto con una variable ... Mire el siguiente ejemplo

DECLARE @myFirstTableID INT DECLARE @mySecondTableID INT INSERT INTO MYFirstTable (....) VALUES (.....) SELECT @myFirstTableID =SCOPE_IDENTITY() INSERT INTO MYSecondTable () VALUES (.....) SELECT @mySecondTableID=SCOPE_IDENTITY()

Por lo tanto, al usar la variable y scope_identity junto a la declaración de inserción de interés, puede asegurarse de obtener la identidad correcta de la tabla correcta. Disfrutar