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

Cómo ejecutar un disparador solo cuando se actualiza una columna específica (SQL Server)

En SQL Server, puede crear activadores DML que ejecutan código solo cuando se actualiza una columna específica.

El disparador aún se activa, pero puede probar si una columna específica se actualizó o no y luego ejecutar el código solo si esa columna se actualizó.

Puedes hacer esto usando UPDATE() función dentro de su gatillo. Esta función acepta el nombre de la columna como argumento. Devuelve un booleano.

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
);

Y aquí está el disparador:

CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;

En este ejemplo, creo una tabla llamada t1 y un disparador llamado trg_t1 .

Yo uso un IF instrucción junto con UPDATE() función para probar si el c1 Se actualizó la columna.

Cuando se ejecuta el disparador, solo ejecutará el código subsiguiente si esa condición es verdadera.

Dispara el gatillo

Insertemos una fila, pero solo insertaremos un valor en el c1 columna.

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Resultado:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 0    | 1    |
+------+------+------+------+

Como era de esperar, el activador se disparó y la columna c3 también se actualizó.

Esto sucedió porque incluí el INSERT argumento en la definición de mi disparador (es decir, especifiqué AFTER INSERT, UPDATE lo que significa que el activador se activa cada vez que se insertan o actualizan datos). Si solo hubiera especificado AFTER UPDATE , no se habría activado cuando inserté datos; solo se activaría cada vez que actualice los datos existentes.

Recuerde que la tabla se definió con DEFAULT 0 , por lo que la columna c2 por defecto es cero.

Ahora actualicemos el c1 columna.

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultado:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 0    | 2    |
+------+------+------+------+

De nuevo, el c3 la columna se actualizó junto con c1 .

Ahora hagamos una actualización del c2 columna (esta columna no está incluida en el disparador).

UPDATE t1 
SET c2 = c2 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultado:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 2    |
+------+------+------+------+

Así que esta vez, c2 fue actualizado pero c3 no fue Eso es porque el c1 la columna no se actualizó y nuestro activador solo actualiza c3 cuando c1 está actualizado.

Lo mismo hubiera sucedido si hubiéramos insertado una fila sin especificar c1 en INSERT declaración.

¿Qué sucede si actualizo la columna con el mismo valor?

Si actualiza una columna con el mismo valor, UPDATE() la función devolverá verdadero.

He aquí un ejemplo.

Sabemos por nuestros ejemplos anteriores que la columna c1 contiene un valor de 2 .

Actualicemos explícitamente esa columna con el mismo valor:1

UPDATE t1 
SET c1 = 2
WHERE id = 1;

SELECT * FROM t1;

Resultado:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 3    |
+------+------+------+------+

Así que ahora c3 ha aumentado, aunque el valor de c1 sigue siendo el mismo.

Hagámoslo de nuevo, pero esta vez configúrelo solo (es decir, cambie c1 = 1 a c1 = c1 ).

UPDATE t1 
SET c1 = c1
WHERE id = 1;

SELECT * FROM t1;

Resultado:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 4    |
+------+------+------+------+

De nuevo, c3 ha aumentado.

Intentos de actualización fallidos

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.