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

Desencadenador de SQL Server:comprensión y alternativas

El activador de SQL Server es un tipo especial de procedimientos almacenados que se ejecuta automáticamente cuando ocurre un evento en un servidor de base de datos específico. SQL Server nos proporciona dos tipos principales de disparadores:el DML Disparadores y el DDL disparadores Los activadores de DDL se activarán en respuesta a diferentes eventos del lenguaje de definición de datos (DDL), como la ejecución de instrucciones CREATE, ALTER, DROP, GRANT, DENY y REVOKE T-SQL. El disparador DDL puede responder a las acciones DDL al evitar que estos cambios afecten la base de datos, realizar otra acción en respuesta a estas acciones DDL o registrar estos cambios que se ejecutan en la base de datos.

El activador DML de SQL Server es un tipo especial de procedimientos almacenados que está diseñado para realizar una secuencia de acciones en una tabla de base de datos, a la que se adjunta el activador, cuando se producen eventos de lenguaje de manipulación de datos (DML), como INSERTAR, ACTUALIZAR o ELIMINAR. acción, se produce para modificar el contenido de las tablas o vistas de la base de datos, independientemente de si las filas de la tabla se ven afectadas o no. Los disparadores se diferencian de los procedimientos almacenados en que los disparadores se activan automáticamente cuando se produce una modificación de datos predefinida. Los disparadores DML se pueden usar para mantener la integridad de los datos y hacer cumplir las reglas comerciales de la empresa, al igual que la funcionalidad de restricciones de verificación de tablas y claves externas, mediante la realización de procesos de auditoría y otras acciones posteriores a DML. Puede usar los disparadores DML para consultar otras tablas y realizar consultas T-SQL complejas.

Si se dispara el disparador, un tipo especial de mesas virtuales llamadas Insertadas y Eliminado Se utilizarán tablas para conservar los valores de los datos antes y después de la modificación. La declaración de disparo funcionará bajo el alcance de la misma transacción que dispara ese disparo. Esto significa que la transacción no se confirmará por completo hasta que la declaración de activación se complete con éxito. Por otro lado, la transacción se revertirá si falla la instrucción desencadenante.

Hay dos tipos de activadores DML:DESPUÉS o PARA desencadenar y EN LUGAR DE generar. El activador DESPUÉS se activará y ejecutará después de realizar la acción INSERTAR, ACTUALIZAR o ELIMINAR que lo activa correctamente. Además, todas las acciones en cascada referenciales y las comprobaciones de restricciones deben tener éxito antes de activar el disparador. El disparador AFTER se puede definir en el nivel de la tabla solo sin la posibilidad de definirlo en las vistas. El disparador INSTEAD OF se usa para anular la declaración de la acción que activa el disparador con la declaración proporcionada en el disparador, revirtiendo esa declaración después de generar un error cuando alguien intenta realizar una acción que infringe una política específica, como actualizar una columna financiera crítica o escribir el cambio en una tabla de auditoría antes de realizar el cambio. El activador INSTEAD OF le permite INSERTAR, ACTUALIZAR o ELIMINAR datos de las vistas que hacen referencia a datos de varias tablas, además de la posibilidad de rechazar una parte de una consulta por lotes y ejecutar otra parte de ese lote con éxito. El disparador INSTEAD OF no se puede usar con las vistas actualizables que tienen CON OPCIÓN DE COMPROBACIÓN y en las tablas con una relación referencial que especifica acciones en cascada en ELIMINAR o ACTUALIZAR.

Después de discutir teóricamente los factores desencadenantes, comenzaremos a mostrar lo que discutimos en la práctica. En las próximas demostraciones, mostraremos las diferentes situaciones en las que podemos beneficiarnos de los disparadores de SQL Server.

DESPUÉS... Activación DML

Suponga que necesitamos rastrear las acciones DML que se realizan en una tabla específica y escribir estos registros en una tabla de historial, donde la ID del registro insertado, actualizado o eliminado y la acción que se realiza se escribirán en la tabla de historial. Las instrucciones CREATE TABLE T-SQL a continuación se pueden usar para crear las tablas de origen y de historial:

CREATE TABLE TriggerDemo_Parent
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT 
  )
GO

CREATE TABLE TriggerDemo_History
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   ParentID INT,
   PerformedAction VARCHAR (50),
  )
GO

Para realizar un seguimiento de la operación INSERTAR, crearemos un disparador DML que se activará después de realizar una operación INSERTAR en la tabla principal. Este activador recuperará el último valor de ID insertado en esa tabla principal desde la tabla virtual insertada, como en la instrucción CREATE TRIGGER T-SQL a continuación:

CREATE TRIGGER AfterInsertTrigger
ON TriggerDemo_Parent
AFTER INSERT
AS
INSERT INTO TriggerDemo_History VALUES ((SELECT TOP 1  inserted.ID FROM inserted), 'Insert')
GO

El seguimiento de la operación DELETE se puede lograr mediante la creación de un activador DML que se activa después de realizar la operación DELETE en la tabla principal. Nuevamente, el activador recuperará el valor de ID del último registro eliminado de esa tabla principal de la tabla eliminada virtual, como en la declaración CREATE TRIGGER T-SQL a continuación:

CREATE TRIGGER AfterDeleteTrigger
ON TriggerDemo_Parent
AFTER DELETE
AS
INSERT INTO TriggerDemo_History VALUES ((SELECT TOP 1  deleted.ID FROM deleted), 'Delete')
GO

Finalmente, rastrearemos también la operación de ACTUALIZACIÓN mediante la creación de un activador DML que se activará después de realizar una operación de ACTUALIZACIÓN en la tabla principal. Dentro de este disparador, recuperaremos el último valor de ID actualizado de esa tabla padre de la tabla virtual insertada, teniendo en cuenta que el proceso de ACTUALIZACIÓN se realiza eliminando el registro e insertando un nuevo registro con los valores actualizados, como en el CREAR TRIGGER Declaración T-SQL a continuación:

CREATE TRIGGER AfterUPDATETrigger
ON TriggerDemo_Parent
AFTER UPDATE
AS
INSERT INTO TriggerDemo_History VALUES ((SELECT TOP 1  inserted.ID FROM inserted), 'UPDATE')
GO

Las tablas y los disparadores ya están listos para nuestras pruebas. Si intenta insertar un nuevo registro en la tabla principal utilizando la declaración INSERT INTO T-SQL a continuación:

INSERT INTO TriggerDemo_Parent VALUES ('AAA','BBB',500)

Luego, al verificar el plan de ejecución generado al ejecutar la instrucción INSERT anterior, verá que se realizarán dos operaciones de inserción que afectarán a dos tablas; la tabla principal con los valores especificados en la declaración INSERT y la tabla de historial debido a la activación del disparador AFTER INSERT, como se muestra en el plan de ejecución a continuación:

También queda claro cuando verifica los datos insertados en las tablas principal y de historial usando las declaraciones SELECT a continuación:

SELECT * FROM TriggerDemo_Parent
GO
SELECT * FROM TriggerDemo_History

Donde los valores especificados en la instrucción INSERT se insertarán en la tabla principal, y el registro de inserción que contiene el ID del registro insertado y la operación realizada se insertarán en la tabla de historial, como se muestra en el resultado a continuación:

Ahora, si intenta actualizar un registro existente en la tabla principal usando la instrucción UPDATE T-SQL a continuación:

UPDATE TriggerDemo_Parent SET Emp_Salary=550 WHERE ID=1

Y verifique el plan de ejecución generado al ejecutar la declaración UPDATE anterior, verá que la operación de actualización será seguida por una operación de inserción que afectará a dos tablas diferentes; la tabla principal se actualizará con el valor especificado en la instrucción UPDATE y la operación de inserción en la tabla de historial debido a la activación del disparador AFTER UPDATE, como se muestra en el plan de ejecución a continuación:

Comprobación de los registros de la tabla principal y del historial mediante las declaraciones SELECT a continuación:

SELECT * FROM TriggerDemo_Parent
GO
SELECT * FROM TriggerDemo_History

Verá que la declaración de actualización modificará el valor Emp_Salary en la tabla principal con el valor especificado en la instrucción UPDATE, y el registro de actualización que contiene el ID del registro actualizado y la operación realizada se insertará en la tabla de historial, como se muestra en el resultado a continuación:

En el último escenario del activador AFTER DML, realizaremos un seguimiento de la eliminación de un registro existente de la tabla principal mediante la instrucción DELETE T-SQL a continuación:

DELETE FROM  TriggerDemo_Parent WHERE ID=1

Luego verifique el plan de ejecución generado al ejecutar la instrucción DELETE anterior, verá que a la operación DELETE le seguirá la operación de inserción, afectando dos tablas diferentes; la tabla principal de la que se eliminará el registro con el ID proporcionado en la cláusula WHERE de la declaración DELETE y la operación de inserción en la tabla de historial debido a la activación del disparador AFTER DELETE, como se muestra en el plan de ejecución a continuación:

Si verifica tanto los registros de la tabla principal como los de la tabla de historial usando las instrucciones SELECT a continuación:

SELECT * FROM TriggerDemo_Parent
GO
SELECT * FROM TriggerDemo_History

Verá que el registro con el valor de ID igual a 1 se eliminó de la tabla principal que se proporciona en la instrucción DELETE, y el registro de eliminación que contiene el ID del registro eliminado y la operación realizada se insertará en la tabla de historial. , como se muestra en el siguiente resultado:

EN LUGAR DE… Disparador DML

El segundo tipo de disparadores DML es el disparador INSTEAD OF DML. Como se mencionó anteriormente, el activador INSTEAD OF anulará la instrucción de la acción que activa el activador con la instrucción proporcionada en el activador. Supongamos que necesitamos registrar las acciones DML que los usuarios intentan realizar en una tabla específica, sin permitirles realizar esa acción. Las declaraciones CREATE TABLE T-SQL a continuación se pueden usar para crear tablas de origen y alternativas:

CREATE TABLE TriggerDemo_NewParent
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT 
  )
GO


CREATE TABLE TriggerDemo_InsteadParent
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   ParentID INT,
   PerformedAction VARCHAR (50),
  )
GO

Después de crear las dos tablas, insertaremos un solo registro en la tabla de origen para nuestra demostración usando la declaración INSERT INTO a continuación:

INSERT INTO TriggerDemo_NewParent VALUES ('AA','BB', 500)

Para esta demostración, crearemos tres disparadores para anular las operaciones INSERTAR, ACTUALIZAR y ELIMINAR. El primer activador se utilizará para evitar cualquier operación de inserción en la tabla principal y el registro que cambia a la tabla alternativa. El disparador se crea usando la instrucción CREATE TRIGGER T-SQL a continuación:

CREATE TRIGGER InsteadOfInsertTrigger
ON TriggerDemo_NewParent
INSTEAD OF INSERT
AS
INSERT INTO TriggerDemo_InsteadParent VALUES ((SELECT TOP 1  inserted.ID FROM inserted), 'Trying to Insert new ID')
GO

El segundo activador se usa para evitar cualquier operación de actualización en la tabla principal y el registro que cambia a la tabla alternativa. Este disparador se crea de la siguiente manera:

CREATE TRIGGER InsteadOfUpdateTrigger
ON TriggerDemo_NewParent
INSTEAD OF UPDATE
AS
INSERT INTO TriggerDemo_InsteadParent VALUES ((SELECT TOP 1  inserted.ID FROM inserted), 'Trying to Update an existing ID')
GO

El último disparador se usará para evitar cualquier operación de eliminación en la tabla principal y el registro que cambia a la tabla alternativa. Este disparador se crea de la siguiente manera:

CREATE TRIGGER InsteadOfDeleteTrigger
ON TriggerDemo_NewParent
INSTEAD OF DELETE
AS
INSERT INTO TriggerDemo_InsteadParent VALUES ((SELECT TOP 1  inserted.ID FROM inserted), 'Trying to Delete an existing ID')
GO

Las dos mesas y los tres activadores ya están listos. Si intenta insertar un nuevo valor en la tabla principal utilizando la declaración INSERT INTO T-SQL a continuación:

INSERT INTO TriggerDemo_NewParent VALUES ('CCC','DDD',500)

Luego verifique los registros de la tabla principal y alternativa usando las instrucciones SELECT a continuación:

SELECT * FROM TriggerDemo_NewParent
GO
SELECT * FROM TriggerDemo_InsteadParent

Debido al hecho de que tenemos el activador INSTEAD OF INSERT en la tabla principal, verá en el resultado que no se inserta ningún registro nuevo en la tabla principal, y se inserta un registro para la operación de inserción en la tabla alternativa, como se muestra en el siguiente resultado:

Intentando actualizar un registro existente en la tabla principal usando la instrucción UPDATE T-SQL a continuación:

UPDATE TriggerDemo_NewParent SET Emp_Salary=550 WHERE ID=1

Luego verifique los registros de la tabla principal y alternativa usando las instrucciones SELECT a continuación:

SELECT * FROM TriggerDemo_NewParent
GO
SELECT * FROM TriggerDemo_InsteadParent

Verá en el resultado que el valor Emp_Salary del registro con el valor de ID igual a 1 de la tabla principal no se cambiará, y el registro para la operación de actualización se inserta en la tabla alternativa debido a que tiene el disparador INSTEAD OF UPDATE en la tabla principal, como se muestra en el siguiente resultado:

Finalmente, si intentamos eliminar un registro existente de la tabla principal usando la declaración DELETE T-SQL a continuación:

DELETE FROM  TriggerDemo_NewParent  WHERE ID=1

Y verifique los registros de la tabla principal y alternativa usando las instrucciones SELECT a continuación:

SELECT * FROM TriggerDemo_NewParent
GO
SELECT * FROM TriggerDemo_InsteadParent

Quedará claro a partir del resultado que el registro con el valor de ID igual a 1 de la tabla principal no se eliminará, y el registro para la operación de eliminación se inserta en la tabla alternativa debido a que tiene el activador INSTEAD OF DELETE en la tabla principal. tabla, como se muestra en el siguiente resultado:

DESPUÉS... Disparador DML con mensajes

El activador AFTER también se puede utilizar para generar un mensaje de advertencia para un usuario. En este caso, la consulta será un mensaje informativo que no impedirá la ejecución de la declaración que dispara ese disparador. Descartemos el disparador INSTEAD OF UPDATE creado anteriormente y reemplácelo con otro disparador DESPUÉS DE ACTUALIZAR que generará un error de advertencia después de realizar cualquier operación de actualización usando las instrucciones DROP/CREATE TRIGGER T-SQL a continuación:

DROP TRIGGER InsteadOfUpdateTrigger
CREATE TRIGGER ReminderTrigger  
ON TriggerDemo_NewParent  
AFTER  UPDATE   
AS RAISERROR ('An Update is performed on the TriggerDemo_NewParent table', 16, 10);  
GO  

Si intenta actualizar el valor Emp_Salary del empleado con el valor de ID igual a 1 usando la instrucción UDPATE a continuación:

UPDATE TriggerDemo_NewParent SET Emp_Salary=550 WHERE ID=1

Aparecerá un mensaje de error en Mensajes pestaña, que contiene el mensaje proporcionado en el disparador creado, como se muestra a continuación:

Verificando los datos de la tabla principal usando la declaración SELECT a continuación:

SELECT * FROM TriggerDemo_NewParent

Verá en el resultado que Emp_Salary se actualizó correctamente, como se muestra a continuación:

Si necesita el activador DESPUÉS DE LA ACTUALIZACIÓN para detener la operación de actualización después de generar el mensaje de error, el ROLLBACK Se puede agregar una declaración al activador para revertir la operación de actualización que activó ese activador, recordando que el activador y la instrucción que activa el activador se ejecutarán en la misma transacción. Esto se puede lograr usando la instrucción ALTER TRIGGER T-SQL, consulte:

ALTER TRIGGER ReminderTrigger  
ON TriggerDemo_NewParent  
AFTER  UPDATE   
AS RAISERROR ('An Update is performed on the TriggerDemo_NewParent table', 16, 10);  
ROLLBACK
GO  

Si intenta actualizar el valor Emp_Salary del empleado con el ID igual a 1 usando la instrucción ACTUALIZAR a continuación:

UPDATE TriggerDemo_NewParent SET Emp_Salary=700 WHERE ID=1

Nuevamente, se mostrará un mensaje de error en Mensajes pero esta vez, la operación de actualización se revertirá por completo, como se muestra en los siguientes mensajes de error:

Verificando el valor de la tabla de origen usando la instrucción SELECT a continuación:

SELECT * FROM TriggerDemo_NewParent

Verá que el valor Emp_Salary no ha cambiado, ya que el activador DESPUÉS DE LA ACTUALIZACIÓN revirtió la transacción general después de generar el mensaje de error, como se muestra en el resultado de la tabla a continuación:

Desventajas de los desencadenantes

Con todas las ventajas mencionadas de los disparadores de SQL Server, los disparadores aumentan la complejidad de la base de datos. Si el disparador está mal diseñado o se usa en exceso, dará lugar a importantes problemas de rendimiento, como sesiones bloqueadas, debido a la extensión de la vida útil de la transacción por más tiempo, sobrecarga adicional en el sistema debido a la ejecución cada vez que un INSERTAR, ACTUALIZAR o Se realiza la acción DELETE o puede provocar problemas de pérdida de datos. Además, no es fácil ver y rastrear los activadores de la base de datos, especialmente si no hay documentación al respecto, ya que es invisible para los desarrolladores y las aplicaciones.

Activar alternativas... Hacer cumplir la integridad

Si se descubre que los activadores están perjudicando el rendimiento de su instancia de SQL Server, debe reemplazarlos con otras soluciones. Por ejemplo, en lugar de usar los activadores para hacer cumplir la integridad de la entidad, debe hacerse cumplir en el nivel más bajo usando las restricciones PRIMARY KEY y UNIQUE. Lo mismo se aplica a la integridad del dominio que debe aplicarse a través de las restricciones CHECK y la integridad referencial que debe aplicarse a través de las restricciones FOREIGN KEY. Puede usar los disparadores DML solo si las funciones admitidas por una restricción específica no pueden cumplir con los requisitos de su aplicación.

Comparemos entre hacer cumplir la integridad del dominio usando disparadores DML y usando las restricciones CHECK. Supongamos que necesitamos forzar la inserción de valores positivos solo en la columna Emp_Salary. Comenzaremos con la creación de una tabla simple usando la instrucción CREATE TABLE T-SQL a continuación:

CREATE TABLE EmployeeSalaryTrigger
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT 
  )
GO

Luego, defina el disparador AFTER INSERT DML que garantiza que inserte un valor positivo en la columna Emp_Salary revirtiendo la transacción si un usuario inserta un valor de salario negativo, usando la instrucción CREATE TRIGGER T-SQL a continuación:

CREATE TRIGGER TRGR_EmployeeSalary ON EmployeeSalaryTrigger 
AFTER INSERT 
AS
DECLARE @EmpSal AS INT
SET @EmpSal = (SELECT TOP 1 inserted.Emp_Salary FROM inserted)
IF @EmpSal<0
BEGIN 
 RAISERROR  ('Cannot insert negative salary',16,10);
  ROLLBACK
END

Para fines de comparación, crearemos otra tabla simple, con el mismo esquema, y ​​definiremos una restricción CHECK dentro de la declaración CREATE TABLE para aceptar solo valores positivos en la columna Emp_Salary, como se muestra a continuación:

CREATE TABLE EmployeeSalaryConstraint
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT CONSTRAINT EmpSal CHECK (Emp_Salary >=0)
  )
GO

Si intenta insertar el siguiente registro que contiene un valor Emp_Salary negativo en la primera tabla que tiene un activador predefinido, utilice la declaración INSERT INTO a continuación:

INSERT INTO EmployeeSalaryTrigger VALUES('Ali', 'Fadi',-4)
GO

La declaración INSERT fallará y generará un mensaje de error que muestra que no puede insertar un valor negativo en la columna Emp_Salary y revertir la transacción general debido a que tiene un activador DESPUÉS DE INSERTAR, como se muestra en el siguiente mensaje de error:

Además, si intenta insertar el mismo registro que contiene un valor Emp_Salary negativo en la segunda tabla que tiene una restricción CHECK predefinida usando la declaración INSERT INTO a continuación:

INSERT INTO EmployeeSalaryConstraint VALUES ('Ali', 'Fadi',-4)

La instrucción INSERT volverá a fallar y mostrará que está intentando insertar el valor que entra en conflicto con la condición de restricción CHECK, como se muestra en el siguiente mensaje de error:

A partir de los resultados anteriores, verá que tanto el desencadenante como el método de restricción CHECK logran el objetivo al evitar que inserte valores Emp_Salary negativos. ¿Pero cual es mejor? Comparemos el rendimiento de los dos métodos comprobando el peso del plan de ejecución para cada uno. A partir de los planes de ejecución generados después de ejecutar las dos consultas, verá que el peso del método de activación es tres veces el peso del método de restricción CHECK, como se muestra en la comparación del plan de ejecución a continuación:

Además, para comparar el tiempo de ejecución consumido por cada uno, ejecutemos cada uno 1000 veces usando las instrucciones T-SQL a continuación:

INSERT INTO EmployeeSalaryTrigger VALUES('Ali', 'Fadi',-4)
GO 10000  
INSERT INTO EmployeeSalaryConstraint VALUES ('Ali', 'Fadi',-4)
GO 10000 

Verá que el primer método que utiliza el activador tardará unos 31 ms. para ser ejecutado completamente, donde el segundo método que usa la restricción CHECK tomará solo 17ms , que es aproximadamente 0,5 del tiempo requerido en el método que usa el disparador. Esto se debe al hecho de que el disparador extenderá la vida de la transacción y revertirá la consulta que activa el disparador después de ejecutarlo cuando se encuentra una violación de integridad, lo que provoca una degradación del rendimiento debido al proceso de reversión. El caso es diferente cuando se usa la restricción CHECK, donde la restricción hará su trabajo antes de realizar cualquier modificación en los datos, sin requerir reversión en caso de violación.

Alternativas de activación... Auditoría

Como mencionamos anteriormente, los disparadores también se pueden usar para auditar y rastrear los cambios realizados en una tabla específica. Si este método de auditoría provoca una degradación del rendimiento en su instancia de SQL Server, puede reemplazarlo fácilmente con OUTPUT cláusula. La cláusula OUTPUT devuelve información sobre cada fila afectada por la operación INSERTAR, ACTUALIZAR o ELIMINAR, en forma de un mensaje de confirmación o un valor que se puede insertar en la tabla histórica. El método de la cláusula OUTPUT también nos brinda más control sobre el código ejecutado, ya que se agregará a la instrucción de inserción, modificación o eliminación de datos en sí cuando lo desee, al contrario que el disparador que se ejecutará siempre.

Comparemos entre registrar la inserción y la modificación de datos en la tabla de historial usando activadores DML y usando la cláusula OUTPUT. Comenzaremos con la creación de las siguientes tablas de producción e historial utilizando la declaración CREATE TABLE T-SQL a continuación:

CREATE TABLE TriggerDemo_Prod
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT 
  )
GO


CREATE TABLE TriggerDemo_ProdHistory
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   ProdID INT,
   ProdSalary INT,
   TS DATETIME,
  )
GO

Una vez que ambas tablas se hayan creado correctamente, crearemos el disparador DESPUÉS DE INSERTAR, ACTUALIZAR DML que escribirá un registro en la tabla de historial si se inserta una nueva fila en la tabla de producción o si se modifica un registro existente mediante la instrucción CREATE TRIGGER T-SQL a continuación:

CREATE TRIGGER ProdHistory
ON TriggerDemo_Prod
AFTER INSERT, UPDATE
AS
INSERT INTO TriggerDemo_ProdHistory  VALUES ( (SELECT TOP 1  inserted.ID FROM inserted),(SELECT TOP 1  inserted.Emp_Salary FROM inserted), GETDATE())
GO

Para comparar el registro de cambios usando el método de disparo y la cláusula OUTPUT, necesitamos crear dos nuevas tablas simples, la producción y las tablas de historial, con el mismo esquema que las dos tablas anteriores, pero esta vez sin definir un disparador, usando el Instrucciones CREATE TABLE T-SQL a continuación:

CREATE TABLE OutputDemo_Prod
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   Emp_First_name VARCHAR (50),
   Emp_Last_name VARCHAR (50),
   Emp_Salary INT 
  )
GO


CREATE TABLE OutputDemo_ProdHistory
(
   ID INT IDENTITY (1,1) PRIMARY KEY,
   ProdID INT,
   ProdSalary INT,
   TS DATETIME,
  )
  
GO

Ahora las cuatro mesas están listas para la prueba. Insertaremos un registro en la primera tabla de producción que tenga un disparador usando la instrucción INSERT INTO T-SQL a continuación:

INSERT INTO TriggerDemo_Prod values('AA','BB', 750)
GO 

Luego insertaremos el mismo registro en la segunda tabla de producción usando la cláusula OUTPUT. La siguiente declaración INSERT INTO actuará como dos declaraciones de inserción; el primero insertará el mismo registro en la tabla de producción y la segunda declaración de inserción al lado de la cláusula OUTPUT insertará el registro de inserción en la tabla de historial:

INSERT INTO OutputDemo_Prod  OUTPUT inserted.ID, inserted.Emp_Salary, GETDATE() 
INTO OutputDemo_ProdHistory	values('AA','BB', 750)
GO 

Al verificar los datos insertados en las cuatro tablas de producción e historial, verá que ambos métodos, el disparador y los métodos de SALIDA, escribirán el mismo registro en la tabla de historial con éxito y de la misma manera, como se muestra en el resultado a continuación:

A partir de los planes de ejecución generados después de ejecutar las dos consultas, verá que el peso del método de activación es aproximadamente (21 %+36 %) 57 % del peso total, donde el peso del método OUTPUT es aproximadamente 43% , con una pequeña diferencia de peso, como se muestra en la comparación de planes de ejecución a continuación:

La diferencia de rendimiento es clara cuando se compara el tiempo de ejecución consumido por cada método, donde el registro de cambios mediante el método de activación consumirá (114+125) 239 ms para ejecutarse por completo, y el método que usa la cláusula OUTPUT consume solo 5ms , que es 2% del tiempo utilizado en el método de activación, como se muestra claramente en las estadísticas de tiempo a continuación:

Está claro ahora del resultado anterior que usar el método OUTPUT es mejor que usar activadores para la auditoría de cambios.

Enlaces útiles:

  • CREAR DISPARADOR (Transact-SQL) https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
  • Activadores DML https://docs.microsoft.com/en-us/sql/relational-databases/triggers/dml-triggers
  • Activadores DDL https://docs.microsoft.com/en-us/sql/relational-databases/triggers/ddl-triggers
  • Cláusula OUTPUT (Transact-SQL) https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql