SQL Server tiene el UPDATE()
función que puede usar dentro de sus disparadores DML para verificar si una columna específica se ha actualizado o no.
Si bien esta función solo acepta una columna, no hay nada que le impida incluir múltiples UPDATE()
cláusulas con AND
o OR
para probar varias actualizaciones de columnas.
Ejemplo
Aquí está la tabla:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0,
c4 int DEFAULT 0
);
Y aquí está el disparador:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) OR UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
En este caso, el c4
la columna se incrementará solo si c1
o c2
Se actualizaron las columnas. Esto ocurrirá incluso si solo se actualiza una de esas dos columnas (debido a que uso OR
a diferencia de AND
).
Ahora probemos el activador insertando datos en c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Resultado:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Como era de esperar, c4
también se actualizó cuando c1
fue actualizado.
Esto también se aplica siempre que c2
está actualizado.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
Y por supuesto, también se aplicaría cuando ambos estén actualizados.
Sin embargo, no aplicar si actualizamos c3
(pero no c1
o c2
).
UPDATE t1
SET c3 = c3 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 1 | 2 | +------+------+------+------+------+
Requerir que se actualicen ambas columnas
Podemos cambiar el OR
a AND
para especificar que el c4
la columna solo se actualiza si ambos c1
y c2
se están actualizando.
Modifiquemos nuestro activador para especificar esto:
ALTER TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) AND UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Ahora actualiza c1
solo.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 2 | 1 | 1 | 2 | +------+------+------+------+------+
Entonces c1
se actualizó según lo especificado, pero c4
no lo era.
Lo mismo sucedería si actualizáramos c2
pero no c1
.
Pero ahora actualicemos ambos c1
y c2
.
UPDATE t1
SET c1 = c1 + 1, c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 3 | 2 | 1 | 3 | +------+------+------+------+------+
Como era de esperar, esta vez c4
también fue actualizado.
Actualizaciones fallidas
Es importante tener en cuenta que UPDATE()
función simplemente indica si un INSERT
o UPDATE
intento se hizo en una columna específica de una tabla o vista. Seguirá siendo verdadero si el intento no tuvo éxito.
La función COLUMNS_UPDATED
Otra forma de buscar actualizaciones en varias columnas es usar COLUMNS_UPDATED
función.
Esta función devuelve un varbinary patrón de bits que indica las columnas insertadas o actualizadas de una tabla o vista.
Para obtener más información, consulte la documentación de Microsoft para COLUMNS_UPDATED
.