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:
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