Cuando crea un activador en SQL Server, tiene la opción de activarlo junto con la declaración de activación (es decir, la instrucción SQL que activó el activador), o activarlo en su lugar de esa declaración.
Para disparar el gatillo en su lugar de la declaración desencadenante, utilice INSTEAD OF
argumento.
Esto contrasta con el uso de FOR
o AFTER
argumentos Cuando usa esos argumentos, el activador se activa solo cuando todas las operaciones especificadas en la instrucción SQL activadora se han iniciado correctamente.
Ejemplo
Cree una tabla de muestra:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Crea el disparador:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Inserte una fila de muestra:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Esto es lo que tenemos hasta ahora:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Ahora ejecutemos una UPDATE
contra la tabla (esto disparará el gatillo).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Como era de esperar, el UPDATE
La declaración en la declaración desencadenante se reemplazó con la del desencadenante.
Mi disparador especificó que cada vez que haya un intento de actualización de la tabla, actualice el c3
columna en su lugar.
Ejecutar solo cuando se actualice una columna específica
También puede usar UPDATE()
función para especificar el código que se ejecutará solo cuando se actualice una columna específica.
Por ejemplo, podríamos modificar nuestro disparador de la siguiente manera:
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Ahora ejecute el UPDATE
anterior declaración de nuevo:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
De nuevo, el c3
la columna se incrementa.
Pero, ahora intentemos actualizar el c2
columna:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Nada cambia. El c3
columna sigue siendo la misma.
Ni siquiera el c2
se actualiza la columna. Esto se debe a que el disparador aún se ejecuta en lugar de la declaración de activación.
Ejecutar activador en lugar de ELIMINAR
Podemos modificar el activador para que se ejecute en lugar de cualquier DELETE
declaraciones.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Ahora intentemos eliminar todas las filas y luego seleccionar todas las filas de la tabla.
DELETE FROM t1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Tenga en cuenta que para que este activador funcione correctamente, tuve que consultar el deleted
tabla en mi disparador (a diferencia del inserted
tabla en los ejemplos anteriores).
Estas dos tablas son creadas y administradas por SQL Server.
El deleted
la tabla almacena copias de las filas afectadas durante DELETE
y UPDATE
declaraciones. Durante la ejecución de un DELETE
o UPDATE
instrucción, las filas se eliminan de la tabla desencadenante y se transfieren a la tabla eliminada.
El inserted
la tabla almacena copias de las filas afectadas durante INSERT
y UPDATE
declaraciones. Durante una transacción de inserción o actualización, se agregan nuevas filas tanto a la tabla insertada como a la tabla desencadenante. Las filas de la tabla insertada son copias de las nuevas filas de la tabla desencadenante.
Algunas restricciones a tener en cuenta
Puede definir un máximo de uno INSTEAD OF
activador por INSERT
, UPDATE
o DELETE
declaración en una tabla o vista.
No puedes definir INSTEAD OF
dispara en vistas actualizables que usan WITH CHECK OPTION
.