En esta entrada exploraremos la diferencia entre estas dos funciones del sistema que mucha gente utiliza y que es sumamente importante conocer el valor que están devolviendo.
Comenzaremos creando dos tablas, en una agregaremos valores y la otra servirá para llevar un historial
muy sencillo de movimientos:
CREATE TABLE TestIdentity(
Id INT IDENTITY(1, 1),
Value VARCHAR(10) NOT NULL
)
GO
CREATE TABLE TestIdentityLog(
Id INT IDENTITY(1, 1),
Task VARCHAR(10),
Value VARCHAR(10)
)
En la tabla TestIdentity iremos guardando valores de prueba y la tabla TestIdentityLog estará guardando el historial de movimientos que se han llevado a cabo sobre la tabla TestIdentity. Debemos notar que en las dos tablas tenemos una columna IDENTITY.
Ahora vamos a crear dos triggers, uno para el INSERT y otro para el DELETE:
CREATE TRIGGER TestIdentity_Insert
ON TestIdentity
FOR INSERT
AS
BEGIN
INSERT INTO TestIdentityLog (Task, Value)
SELECT 'INSERT', Value
FROM INSERTED
END
GO
CREATE TRIGGER TestIdentity_Delete
ON TestIdentity
FOR DELETE
AS
BEGIN
INSERT INTO TestIdentityLog (Task, Value)
SELECT 'DELETE', Value
FROM DELETED
END
Ambos guardan el movimiento en la tabla de historial, sólo que el primero es para INSERT y el segundo para DELETE
Vamos a crear un procedimiento almacenado para agregar un valor a TestIdentity, de paso mostraremos el resultado
de la ejecución de los dos valores que nos interesan: @@IDENTITY y SCOPE_IDENTITY():
CREATE PROC pAddValue(
@Value VARCHAR(10)
)
AS
BEGIN
INSERT INTO TestIdentity (Value)
VALUES (@Value)
PRINT '@@IDENTITY: ' + CAST(@@IDENTITY AS VARCHAR)
PRINT 'SCOPE_IDENTITY(): ' + CAST(SCOPE_IDENTITY() AS VARCHAR)
END
Ahora vamos a crear un procedimiento almacenado que nos permita eliminar un elemento de la tabla TestIdentity:
CREATE PROC pDeleteValue(
@Id INT
)
AS
BEGIN
DELETE TestIdentity
WHERE Id = @Id
END
Habitualmente se piensa que podemos utilizar cualquiera de los dos sin problema, pero al ejecutar el siguiente código
veremos que ambas nos mostrarán números diferentes en la tercera ejecución:
SET NOCOUNT ON
GO
EXEC pAddValue 'Valor 1'
GO
EXEC pDeleteValue 1
GO
EXEC pAddValue 'Valor 1'
El primer EXEC mostrará que @@IDENTITY devuelve 1 y SCOPE_IDENTITY() devuelve 1, pero veremos que el tercer EXEC mostrará que @@IDENTITY devuelve 3 y SCOPE_IDENTITY() devuelve 2.
Esto se debe a que @@IDENTITY devuelve el último valor obtenido a través de una columna IDENTITY, este valor pertence a la columna Id de la tabla TestIdentityLog, los trigger que se están disparando ante el INSERT o DELETE son los que están realizando esa inserción y por lo tanto el último valor asignado es el de la tabla TestIdentityLog.
La función SCOPE_IDENTITY() devuelve el último valor asignado por IDENTITY en el entorno actual de ejecución, para nuestro procedimiento pAddValue el único IDENTITY que tiene a su alcance es el que está en la columna Id de la tabla TestIdentity, es por ello que devuelve el valor 2.
Como podrás notar, es importante conocer la diferencia entre las dos opciones que tenemos, dependerá del objetivo del procedimiento o de la operación cuál te resulte adecuado a tus necesidades; generalmente utilizarás SCOPE_IDENTITY()
Espero esta entrada te haya resultado útil, nos vemos la siguiente.
No hay comentarios.:
Publicar un comentario