sql >> Base de Datos >  >> RDS >> Sqlserver

Ejecutar un disparador solo cuando se actualicen ciertas columnas (SQL Server)

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 .