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

Cree un disparador "En lugar de" en SQL Server

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 .