Triggers en Transact SQLUn trigger (disparador o desencadenador) es una clase especial de procedimiento almacenado que se ejecuta automáticamente cuando se produce un evento en el servidor de bases de datos. SQL Server proporciona los siguientes tipos de triggers: • Trigger DML, se ejecutan cuando un usuario intenta modificar datos mediante un evento de lenguaje de manipulación de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una tabla o vista. • Trigger DDL, se ejecutan en respuesta a una variedad de eventos de lenguaje de definición de datos (DDL). Estos eventos corresponden principalmente a instrucciones CREATE, ALTER y DROP de Transact-SQL, y a determinados procedimientos almacenados del sistema que ejecutan operaciones de tipo DDL. Trigger DML. Los trigger DML se ejecutan cuando un usuario intenta modificar datos mediante un evento de lenguaje de manipulación de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una tabla o vista. La sintaxis general de un trigger es la siguiente. CREATE TRIGGER <Trigger_Name, sysname, Trigger_Name> ON <Table_Name, sysname, Table_Name> AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE> AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for trigger here END Antes de ver un ejemplo es necesario conocer las tablas inserted y deleted. Las instrucciones de triggers DML utilizan dos tablas especiales denominadas inserted y deleted. SQL Server 2005 crea y administra automáticamente ambas tablas. La estructura de las tablas inserted y deleted es la misma que tiene la tabla que ha desencadenado la ejecución del trigger. La primera tabla (inserted) solo está disponible en las operaciones INSERT y UPDATE y en ella están los valores resultantes después de la inserción o actualización. Es decir, los datos insertados. Inserted estará vacía en una operación DELETE. En la segunda (deleted), disponible en las operaciones UPDATE y DELETE, están los valores anteriores a la ejecución de la actualización o borrado. Es decir, los datos que serán borrados. Deleted estará vacía en una operación INSERT. ¿No existe una tabla UPDATED? No, hacer una actualización es lo mismo que borrar (deleted) e insertar los nuevos (inserted). La sentencia UPDATE es la única en la que inserted y deleted tienen datos simultáneamente. No se puede modificar directamente los datos de estas tablas. El siguiente ejemplo, graba un histórico de saldos cada vez que se modifica un saldo de la tabla cuentas. CREATE TRIGGER TR_CUENTAS ON CUENTAS AFTER UPDATE AS BEGIN -- SET NOCOUNT ON impide que se generen mensajes de texto -- con cada instrucción SET NOCOUNT ON; INSERT INTO HCO_SALDOS (IDCUENTA, SALDO, FXSALDO) SELECT IDCUENTA, SALDO, getdate() FROM INSERTED END La siguiente instrucción provocará que el trigger se ejecute: UPDATE CUENTAS SET SALDO = SALDO + 10 WHERE IDCUENTA = 1 Una consideración a tener en cuenta es que el trigger se ejecutará aunque la instrucción DML (UPDATE, INSERT o DELETE ) no haya afectado a ninguna fila. En este caso inserted y deleted devolverán un conjunto de datos vacío. Podemos especificar a que columnas de la tabla debe afectar el trigger. ALTER TRIGGER TR_CUENTAS ON CUENTAS AFTER UPDATE AS BEGIN -- SET NOCOUNT ON impide que se generen mensajes de texto -- con cada instrucción SET NOCOUNT ON; IF UPDATE(SALDO) -- Solo si se actualiza SALDO BEGIN INSERT INTO HCO_SALDOS (IDCUENTA, SALDO, FXSALDO) SELECT IDCUENTA, SALDO, getdate() FROM INSERTED END END Los trigger están dentro de la transacción original (Insert, Delete o Update) por lo cual si dentro de nuestro trigger hacemos un RollBack Tran, no solo estaremos echando atrás nuestro trigger sino también toda la transacción; en otras palabras si en un trigger ponemos un RollBack Tran, la transacción de Insert, Delete o Update volverá toda hacia atrás. ALTER TRIGGER TR_CUENTAS ON CUENTAS AFTER UPDATE AS BEGIN -- SET NOCOUNT ON impide que se generen mensajes de texto -- con cada instrucción SET NOCOUNT ON; INSERT INTO HCO_SALDOS (IDCUENTA, SALDO, FXSALDO) V.nart) begin insert into articulos (nart. nart. UNIDADES. NOMBRE.nart=i. PPU) values (60. NART.NEMP.SELECT IDCUENTA. '12-05-2011'. unidades from inserted end nemp.UNIDADES*A. getdate() FROM INSERTED ROLLBACK END En este caso obtendremos el siguiente mensaje de error: La transacción terminó en el desencadenador. FECHA.ppu from inserted i end insert into ventas (nemp.nemp from empleados e.'Ivan'. fecha. V.nombre from inserted i end if not exists (select a. V.FECHA. inserted i where a. 1. CREATE VIEW VVENTAS AS SELECT E.PPU 'IMPORTE' FROM (EMPLEADOS E INNER JOIN VENTAS V ON V.NART. fecha. select * from articulos.nemp) begin insert into empleados (nemp. NOMBRE. 30) insert into vventas (NEMP.nart from articulos a.NEMP=E.'pepe'. UNIDADES. 1. NOMBRE.ppu) select i. i. PPU) values (60. Se anuló el lote.UNIDADES. PPU) values (1. 101.NEMP) INNER JOIN ARTICULOS A ON A. SALDO. V. UNIDADES. '12-05-2011'. 2.'Ivan'. NART. i. 30) select * from empleados.NART = V. '12-05-2011'. inserted i where e.nart. 30) insert into vventas (NEMP. select * from vventas CREATE TRIGGER insertaVVentas ON vventas INSTEAD OF INSERT AS begin SET NOCOUNT ON if not exists (select e.PPU. E.nombre) select i.nemp.nemp=i. 2.NOMBRE. 2. FECHA. NART.NART insert into vventas (NEMP. . FECHA. unidades) select nart. A. Activa todos los trigger de la tabla CUENTAS ALTER TABLE CUENTAS ENABLE TRIGGER ALL . -.Cierre del cursor CLOSE cBorrados -.activa el trigger TR_CUENTAS ENABLE TRIGGER TR_CUENTAS ON CUENTAS GO -.Desactiva todos los trigger de la tabla CUENTAS ALTER TABLE CUENTAS DISABLE TRIGGER ALL GO -.Desactiva el trigger TR_CUENTAS DISABLE TRIGGER TR_CUENTAS ON CUENTAS GO -.nemp from deleted d where d.Liberar los recursos DEALLOCATE cBorrados end Podemos activar y desactivar Triggers a través de las siguientes instrucciones.ndep <> 1 OPEN cBorrados FETCH cBorrados INTO @nemp WHILE (@@FETCH_STATUS = 0 ) BEGIN delete from ventas where nemp=@nemp delete from empleados where nemp = @nemp FETCH cBorrados INTO @nemp END -.CREATE TRIGGER noBorrarDep1BIS ON empleados INSTEAD OF delete AS begin SET NOCOUNT ON declare @nemp int declare cborrados cursor for select d. Los eventos DML son instrucciones INSERT. . CREATE TRIGGER <trigger_name.. CREATE TRIGGER TR_SEGURIDAD ON DATABASE FOR DROP_TABLE. ALTER_TABLE AS BEGIN RAISERROR ('No está permitido borrar ni modificar tablas !' . y a determinados procedimientos almacenados del sistema que ejecutan operaciones de tipo DDL. table_alter_drop_safety> ON DATABASE FOR <data_definition_statements.. . Los desencadenadores DML se ejecutan cuando un usuario intenta modificar datos mediante un evento de lenguaje de manipulación de datos (DML).NET Framework y se cargan en una instancia de SQL Server. Estos eventos corresponden principalmente a instrucciones CREATE. sysname. SQL Server permite crear varios desencadenadores para una instrucción específica. 16. 1) ROLLBACK TRANSACTION END Crea un desencadenador DML o DDL.Trigger DDL Los trigger DDL se ejecutan en respuesta a una variedad de eventos de lenguaje de definición de datos (DDL). Los desencadenadores DDL se ejecutan en respuesta a una variedad de eventos de lenguaje de definición de datos (DDL). ALTER_TABLE> AS BEGIN . END La siguiente instrucción impide que se ejecuten sentencias DROP TABLE y ALTER TABLE en la base de datos. ALTER y DROP de Transact-SQL. ALTER y DROP. Consisten principalmente en instrucciones CREATE. La sintaxis general de un trigger es la siguiente. Un desencadenador es una clase especial de procedimiento almacenado que se ejecuta automáticamente cuando se produce un evento en el servidor de bases de datos. UPDATE o DELETE de una tabla o vista. DROP_TABLE. Los desencadenadores DML y DDL se pueden crear en el SQL Server 2005 Database Engine (Motor de base de datos de SQL Server 2005) directamente a partir de instrucciones Transact-SQL o de métodos de ensamblados que se crean en Common Language Runtime (CLR) de Microsoft . or UPDATE STATISTICS statement (DDL Trigger) CREATE TRIGGER trigger_name ON { ALL SERVER | DATABASE } [ WITH <ddl_trigger_option> [ .. Para obtener más información acerca de cómo mitigar esta amenaza.n ] ] { FOR | AFTER } { event_type | event_group } [ ...class_name. UPDATE. ] [ . ] [ DELETE ] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS { sql_statement [ . GRANT...n ] | EXTERNAL NAME <method specifier [ .n ] AS { sql_statement [ . DROP. ] > } <dml_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ] <method_specifier> ::= assembly_name.method_name . Convenciones de sintaxis de Transact-SQL Sintaxis Trigger on an INSERT. ALTER.Seguridad Nota: El código dañino de los desencadenadores se puede ejecutar bajo privilegios escalados..class_name.. or DELETE statement to a table or view (DML Trigger) CREATE TRIGGER [ schema_name . ] [ .n ] | EXTERNAL NAME < method specifier > [ .method_name Trigger on a CREATE. DENY. ]trigger_name ON { table | view } [ WITH <dml_trigger_option> [ ... vea Administrar la seguridad de los desencadenadores..... ] [ UPDATE ] [ . REVOKE. ] } <ddl_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ] <method_specifier> ::= assembly_name.n ] ] { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ . Sin embargo. al desencadenador no se lo llama de forma recursiva. DRI no proporciona integridad referencial entre bases de datos. Un desencadenador AFTER se ejecuta sólo después de ejecutar correctamente la instrucción SQL desencadenadora. Sólo se puede especificar el primer y último desencadenador AFTER para cada una de las operaciones INSERT. utilice las restricciones de tipo PRIMARY KEY y FOREIGN KEY en ALTER TABLE y CREATE TABLE. La ejecución correcta incluye todas las acciones referenciales en cascada y las comprobaciones de restricciones asociadas con el objeto actualizado o eliminado. Si se infringen las restricciones. la instrucción se procesa como si la tabla no tuviera un desencadenador INSTEAD OF e inicia la cadena de operaciones . se elimina el primer o último atributo establecido en el desencadenador modificado. se comprueban después de la ejecución del desencadenador INSTEAD OF y antes de la de AFTER. Para exigir la integridad referencial. se ejecutan aleatoriamente. se revierten las acciones del desencadenador INSTEAD OF y el desencadenador AFTER no se ejecuta. Si un desencadenador INSTEAD OF definido en una tabla ejecuta una instrucción en la tabla que normalmente volvería a activarlo.Notas Desencadenadores DML Los desencadenadores DML se utilizan frecuentemente para imponer las reglas empresariales y la integridad de los datos. Si existen restricciones en la tabla de desencadenadores. El primer y último desencadenador AFTER que se ejecuta en una tabla se puede especificar mediante sp_settriggerorder. Si una instrucción ALTER TRIGGER modifica el primer o último desencadenador. En su lugar. y el valor del orden se debe restablecer mediante sp_settriggerorder. La integridad referencial se refiere a las reglas acerca de la relación entre la clave principal y la clave externa de las tablas. SQL Server proporciona integridad referencial declarativa (DRI) mediante las instrucciones ALTER TABLE y CREATE TABLE. UPDATE y DELETE de una tabla. Si hay otros desencadenadores AFTER en la misma tabla. En este caso. Por ejemplo. utilice UPDATE() o COLUMNS_UPDATED en el cuerpo del desencadenador. la instrucción UPDATE. vea Modificar datos mediante una vista. UPDATE() comprueba los intentos de UPDATE o INSERT en una columna. Si un desencadenador INSTEAD OF definido en una vista ejecuta una instrucción en la vista que normalmente volvería a activarlo. Probar las acciones de UPDATE o INSERT en columnas específicas Se puede diseñar un desencadenador Transact-SQL que realice determinadas acciones según modificaciones de UPDATE o INSERT en columnas específicas. no vuelve a llamar al desencadenador. la definición de la vista debe cumplir todas las restricciones para una vista actualizable. Para obtener una definición de vistas actualizables. y éste ejecuta una instrucción INSERT en la misma tabla. si para una tabla se define un desencadenador como INSTEAD OF UPDATE y éste ejecuta una instrucción UPDATE que hace referencia a la misma vista. si para una tabla se define un desencadenador como INSTEAD OF INSERT. La instrucción INSERT ejecutada por el desencadenador inicia el proceso que realiza las acciones de restricción y activa cualquier desencadenador AFTER INSERT definido para la tabla. que ejecuta el desencadenador INSTEAD OF. Por ejemplo. La instrucción UPDATE que ejecuta el desencadenador se procesa en la vista. Cada vez que se modifica una tabla base subyacente se inicia la cadena para aplicar restricciones y activar los desencadenadores AFTER definidos para la tabla. como si ésta no tuviera un desencadenador INSTEAD OF. no se llamará el desencadenador de forma recursiva. la instrucción INSERT ejecutada por el desencadenador INSTEAD OF no vuelve a llamar al desencadenador. En su lugar. Para ello. COLUMNS_UPDATED comprueba las acciones de UPDATE o INSERT que se realizaron en varias columnas y devuelve un patrón de bits que indica las columnas que fueron insertadas o actualizadas.de restricción y ejecuciones de desencadenadores AFTER. . Las columnas que modifica la instrucción UPDATE deben resolverse en una única tabla base. la instrucción se resuelve a modo de modificaciones en las tablas base subyacentes de la vista. En un desencadenador se puede especificar cualquier instrucción SET. Aunque una instrucción TRUNCATE TABLE es.Limitaciones de los desencadenadores CREATE TRIGGER debe ser la primera instrucción en el proceso por lotes y sólo se puede aplicar a una tabla. sin embargo. Un desencadenador que incluya instrucciones SELECT que devuelven resultados al usuario o instrucciones que realizan asignaciones de variables requiere un tratamiento especial. después. los resultados se devuelven a la aplicación que llama. utilice una instrucción SET NOCOUNT al principio del mismo para impedir la devolución de cualquier conjunto de resultados. La misma acción del desencadenador puede definirse para más de una acción del usuario (por ejemplo. no incluya las instrucciones SELECT que devuelven resultados ni las instrucciones que realizan una asignación variable en un desencadenador. Un desencadenador se crea solamente en la base de datos actual. Si es preciso que existan asignaciones de variable en un desencadenador. un desencadenador puede hacer referencia a objetos que están fuera de la base de datos actual. Los desencadenadores INSTEAD OF DELETE/UPDATE no pueden definirse en una tabla con una clave externa definida en cascada en la acción DELETE/UPDATE. califique el nombre de la tabla de la misma forma. Un desencadenador DELETE no captura una instrucción TRUNCATE TABLE. estos resultados devueltos tendrían que escribirse en cada aplicación en la que se permiten modificaciones a la tabla del desencadenador. vuelve a su configuración anterior. INSERT y UPDATE) en la misma instrucción CREATE TRIGGER. Si se especifica el nombre del esquema del desencadenador (para calificar el desencadenador). exactamente igual que con los procedimientos almacenados. . Para impedir que se devuelvan resultados a la aplicación debido a la activación de un desencadenador. La opción SET seleccionada permanece en efecto durante la ejecución del desencadenador y. Cuando se activa un desencadenador. de hecho. La instrucción WRITETEXT. modificar o quitar columnas. las siguientes instrucciones Transact-SQL no se permiten en el cuerpo de un desencadenador DML cuando éste se utiliza en la tabla o vista que es objeto de la acción desencadenadora. se exige cuando el modo de compatibilidad con versiones anteriores es igual a 80. no se registra y. un desencadenador DELETE sin una cláusula WHERE (quita todas las filas). • • ALTER PARTITION DROP FUNCTION TABLE Cambiar particiones. Dado que el permiso de la instrucción TRUNCATE TABLE es del propietario de la tabla y no se puede transferir. no activa un desencadenador. DROP CREATE INDEX ALTER INDEX INDEX DBCC DBREINDEX ALTER TABLE cuando se utiliza para hacer lo siguiente: Agregar. sólo el propietario de la tabla debe preocuparse de invocar sin darse cuenta una instrucción TRUNCATE TABLE que no producirá la ejecución del desencadenador DELETE. ya se registre o no. por tanto. no puede ejecutar un desencadenador. Las siguientes instrucciones Transact-SQL no están permitidas en un desencadenador DML: ALTER DATABASE LOAD DATABASE RESTORE DATABASE CREATE DATABASE LOAD LOG RESTORE LOG DROP DATABASE RECONFIGURE Además. . Importante: Aunque esta restricción se ha introducido en SQL Server 2005. Entre ellas se incluyen instrucciones CREATE. INSERT o DELETE en una tabla o vista. REVOKE y UPDATE STATISTICS. Para obtener más información acerca de los desencadenadores DDL. Los . Los desencadenadores DDL con ámbito en la base de datos aparecen en la carpeta Database Triggers. DROP. vea Desencadenadores DDL. OBJECT_NAME. se ejecutan principalmente como respuesta a instrucciones de lenguaje de definición de datos (o DDL). al igual que los estándar. Por tanto. no se ejecutan como respuesta a instrucciones UPDATE. Utilice en su lugar las vistas de catálogo.Agregar o quitar restricciones de tipo PRIMARY KEY o UNIQUE. En cambio. Para obtener más información. Dicha carpeta se encuentra en la carpeta Server Objects. ALTER. vea Obtener información acerca de los desencadenadores DDL. DENY. A diferencia de los desencadenadores DML. GRANT. ejecutan procedimientos almacenados como respuesta a un evento. en la carpeta Triggers. OBJECT_ID. OBJECTPROPERTY y OBJECTPROPERTYEX no se pueden utilizar para efectuar consultas en metadatos sobre desencadenadores DDL. se recomienda no crearlos. los desencadenadores DDL no tienen como ámbito los esquemas. Desencadenadores DDL Los desencadenadores DDL. Nota: Los desencadenadores DDL con ámbito en el servidor aparecen en el Explorador de objetos de SQL Server Management Studio. Pero a diferencia de los desencadenadores estándar. • Nota: Ya que SQL Server no admite desencadenadores definidos por el usuario en tablas del sistema. Consideraciones generales sobre los desencadenadores Devolver resultados Se quitará la capacidad de devolver resultados desde los desencadenadores en una futura versión de SQL Server. Esta carpeta se encuentra en la carpeta Programación de la base de datos correspondiente. se creará un desencadenador de actualización adicional. En las versiones anteriores de SQL Server. cualquier desencadenador creado con la instrucción CREATE TRIGGER substituirá a los desencadenadores existentes del mismo tipo. SQL Server devuelve un mensaje de error. La configuración predeterminada de esta opción será 1 en una futura versión de SQL Server. si el nivel de compatibilidad es igual o menor que 65. vea sp_dbcmptlevel (Transact-SQL). Los desencadenadores recursivos permiten dos tipos de repetición: • Repetición indirecta . Si el nombre de los desencadenadores es el mismo. Nota: Con un nivel de compatibilidad de 70. Por ejemplo. Desencadenadores múltiples SQL Server permite que se creen varios desencadenadores por cada evento DML o DDL. el comportamiento predeterminado de CREATE TRIGGER es agregar desencadenadores adicionales a los ya existentes si los nombres de desencadenadores son distintos. Evite la devolución de conjuntos de resultados desde desencadenadores en los nuevos trabajos de desarrollo y piense en modificar las aplicaciones que la usan actualmente. sólo se permitía un desencadenador por cada evento de modificación (INSERT. DELETE) en cada tabla. establezca disallow results from triggers (opción) en 1. UPDATE. Para obtener más información. si se ejecuta CREATE TRIGGER FOR UPDATE para una tabla que ya tiene un desencadenador UPDATE. Desencadenadores recursivos SQL Server permite también la invocación recursiva de desencadenadores cuando el valor RECURSIVE_TRIGGERS está habilitado mediante ALTER DATABASE. Sin embargo. Para evitar que los desencadenadores devuelvan conjuntos de resultados en SQL Server 2005. incluso si los nombres de los desencadenadores son distintos.desencadenadores que devuelven conjuntos de resultados pueden provocar comportamientos inesperados en aplicaciones que no están diseñadas para trabajar con ellos. y así sucesivamente. Además. Deshabilitar RECURSIVE_TRIGGERS sólo evita las repeticiones directas. Las tablas inserted y deleted de un desencadenador específico contienen filas que corresponden sólo a la instrucción UPDATE que invocó al desencadenador. la ejecución de TR1 desencadena la ejecución de TR1 (recursivamente) y TR2. el segundo se activa y puede. • Repetición directa Con la repetición directa. Desencadenadores anidados Los desencadenadores pueden anidarse hasta un máximo de 32 niveles. TR1 y TR2. Cada desencadenador debe ser independiente. Debido a que la tabla T1 se ha actualizado. y así sucesivamente. directa e indirecta. Así se activa el desencadenador TR1 para actualizar la tabla T1. Este ejemplo utiliza ambas repeticiones de desencadenador. Si un desencadenador cambia una tabla en la que hay otro desencadenador. En esta situación. el nivel de . independientemente del nivel de anidamiento. el desencadenador TR1 se activa de nuevo. una aplicación actualiza la tabla T1. Suponga que en la tabla T1 se han definido dos desencadenadores de actualización. Así se activa el desencadenador TR1 para actualizar la tabla T2.Con la repetición indirecta. establezca la opción nested triggers del servidor en 0 con sp_configure. Si alguno de los desencadenadores ejecuta una instrucción ROLLBACK TRANSACTION. No hay un orden definido en el que se ejecuten los distintos desencadenadores definidos de un evento específico. llamar a un tercero. el desencadenador T2 activa y actualiza la tabla T1. no se ejecuta ningún desencadenador posterior. una aplicación actualiza la tabla T1. Nota: El comportamiento anterior sólo se produce si el valor RECURSIVE_TRIGGERS está habilitado mediante ALTER DATABASE. entonces. Si algún desencadenador de la cadena causa un bucle infinito. Para deshabilitar la repetición indirecta. El desencadenador TR1 actualiza la tabla T1 recursivamente. Una instrucción UPDATE ejecuta cada TR1 y TR2 una vez. La configuración predeterminada permite desencadenadores anidados. se devuelve un mensaje de error en tiempo de ejecución. si los procedimientos almacenados. Si los desencadenadores anidados están desactivados. Sin embargo. independientemente del valor de RECURSIVE_TRIGGERS establecido mediante ALTER DATABASE. Si se utiliza un proceso por lotes. esta referencia cuenta como un nivel para el límite de anidamiento de 32 niveles. Para deshabilitar los desencadenadores anidados. vea Resolución diferida de nombres y compilación. se emitirá una advertencia en el momento de la creación sólo si el valor de nivel de compatibilidad se establece en 65. con lo que se cancela el desencadenador. establezca la opción nested triggers de sp_configure en 0 (desactivada). Si la tabla a la que se hace referencia no existe. desencadenadores y procesos por lotes de Transact-SQL hagan referencia a tablas que no existen en el momento de la compilación. Para obtener más información. Argumentos schema_name Es el nombre del esquema al que pertenece un desencadenador DML. trigger_name . desencadenadores y procesos por lotes de Transact-SQL hacen referencia a una tabla definida en el procedimiento almacenado o desencadenador. los desencadenadores recursivos también se deshabilitan.anidamiento se habrá sobrepasado. No se puede especificar schema_name para desencadenadores DDL. un tipo o agregado CLR. Esta capacidad se denomina resolución diferida de nombres. Nota: Cuando un desencadenador Transact-SQL ejecuta código administrado haciendo referencia a una rutina. Resolución diferida de nombres SQL Server permite que los procedimientos almacenados. la advertencia se emite en el momento de la compilación. Los métodos invocados desde el código administrado no cuentan para este límite. Los desencadenadores DML se limitan al esquema de la tabla o vista en la que se crearon. Para obtener más información. Sólo se puede hacer referencia a una vista mediante un desencadenador INSTEAD OF. el desencadenador se activa cada vez que event_type o event_group tienen lugar en la base de datos actual. Si se especifica. ALL SERVER Aplica el ámbito de un desencadenador DDL al servidor actual. WITH ENCRYPTION no se puede especificar para desencadenadores CLR. EXECUTE AS Especifica el contexto de seguridad en el que se ejecuta el desencadenador. El uso de WITH ENCRYPTION impide que el desencadenador se publique como parte de la réplica de SQL Server. Permite controlar qué cuenta de usuario utiliza la instancia de SQL Server para validar los permisos sobre cualquier objeto de base de datos al que haga referencia el desencadenador. vea EXECUTE AS (cláusula de Transact-SQL). algunas veces se denomina tabla del desencadenador o vista del desencadenador. AFTER Especifica que el desencadenador DML sólo se activa . Si se especifica. Especificar el nombre completo de la tabla o vista es opcional. El parámetro trigger_name debe cumplir con las reglas de los identificadores. WITH ENCRYPTION Codifica el texto de la instrucción CREATE TRIGGER. el desencadenador se activa cada vez que event_type o event_group tienen lugar en la base de datos actual. con la excepción de que trigger_name no puede comenzar con los símbolos # o ##. table | view Es la tabla o vista en que se ejecuta el desencadenador DML. DATABASE Aplica el ámbito de un desencadenador DDL a la base de datos actual.Es el nombre del desencadenador. en cualquier orden. en las vistas es posible definir otras vistas que tengan su propio desencadenador INSTEAD OF. Igualmente. Se debe especificar al menos una opción. por lo que se suplantan las acciones de las instrucciones desencadenadoras. Para los desencadenadores INSTEAD OF. INSTEAD OF no se puede especificar para desencadenadores DDL. ] [ UPDATE ] } Especifica las instrucciones de modificación de datos que activan el desencadenador DML cuando se intenta en esta tabla o vista. Como máximo. no se permite la opción DELETE en tablas que tengan una relación de integridad referencial que especifica una acción ON DELETE en cascada. Además. Los desencadenadores INSTEAD OF no se pueden utilizar en vistas actualizables que usan WITH CHECK OPTION. todas las acciones referenciales en cascada y las comprobaciones de restricciones deben ser correctas para que este desencadenador se ejecute. SQL Server genera un error cuando se agrega un desencadenador INSTEAD OF a una vista actualizable para la que se especificó WITH CHECK OPTION. No obstante.cuando todas las operaciones especificadas en la instrucción SQL desencadenadora se han ejecutado correctamente. En la definición del desencadenador se permite cualquier combinación de estas opciones. El usuario debe quitar esta opción mediante ALTER VIEW antes de definir el desencadenador INSTEAD OF. Los desencadenadores AFTER no se pueden definir en las vistas. se puede definir un desencadenador INSTEAD OF por cada instrucción INSERT. { [ DELETE ] [ . UPDATE o DELETE en cada tabla o vista. AFTER es el valor predeterminado cuando sólo se especifica la palabra clave FOR. no se permite la opción UPDATE en tablas que tengan una relación de integridad referencial que . INSTEAD OF Especifica que se ejecuta el desencadenador DML en vez de la instrucción SQL desencadenadora. ] [ INSERT ] [ . Los grupos de eventos válidos para su uso en desencadenadores DDL se enumeran en Utilizar grupos de eventos con desencadenadores DDL. Para obtener más información. Una vez que CREATE TRIGGER ha terminado de ejecutarse.trigger_events. event_type Es el nombre de un evento de lenguaje Transact-SQL que hace que. Éste es el comportamiento predeterminado de CREATE TRIGGER cuando el nivel de compatibilidad es 70 o superior. event_group también actúa como una macro al agregar los tipos de eventos que comprende a la vista de catálogo sys. se active un desencadenador DDL. La utilización de esta cláusula opcional sólo es necesaria cuando el nivel de compatibilidad es 65 o inferior. vea sp_dbcmptlevel (TransactSQL). una vez ejecutado. Si el nivel de compatibilidad es 70 o superior. WITH APPEND no se puede utilizar con desencadenadores INSTEAD OF o cuando se ha declarado AFTER explícitamente. WITH APPEND Especifica que debe agregarse un desencadenador adicional de un tipo existente.especifica una acción ON UPDATE en cascada. WITH APPEND no se puede especificar si se ha especificado EXTERNAL NAME (es decir. Importante: WITH APPEND se quitará en una versión futura de Microsoft . Los eventos válidos para su uso en desencadenadores DDL se enumeran en Utilizar eventos de DDL con desencadenadores DDL. no es necesaria la cláusula WITH APPEND para agregar un desencadenador adicional de un tipo existente. event_group Es el nombre de un agrupamiento predefinido de eventos de lenguaje de Transact-SQL. si el desencadenador es de tipo CLR). WITH APPEND sólo se puede utilizar si se especificó FOR (sin INSTEAD OF ni AFTER) por motivos de compatibilidad con versiones anteriores. El desencadenador DDL se activa tras la ejecución de cualquier evento de lenguaje Transact-SQL que pertenezca a event_group. Los desencadenadores pueden incluir cualquier número y clase de instrucciones Transact-SQL. Las instrucciones Transact-SQL de un desencadenador incluyen a menudo lenguaje de control de flujo. Evite su uso en los nuevos trabajos de desarrollo y piense en modificar las aplicaciones que la usan actualmente. Las tablas deleted e inserted guardan los valores antiguos o nuevos de las filas que la acción del usuario puede cambiar. no debe devolver datos al usuario. Los desencadenadores DML usan las tablas lógicas (conceptuales) deleted e inserted. la tabla en que se intenta la acción del usuario. Las condiciones del desencadenador especifican los criterios adicionales que determinan si los intentos de las instrucciones DML o DDL hacen que se lleven a cabo las acciones del desencadenador. Son de estructura similar a la tabla en que se define el desencadenador. Las acciones del desencadenador especificadas en las instrucciones Transact-SQL surten efecto cuando se intenta la operación DML o DDL. Para obtener más información. NOT FOR REPLICATION Indica que el desencadenador no debe ejecutarse cuando un agente de réplica modifica la tabla involucrada en el mismo. utilice: Copiar código SELECT * FROM deleted Para obtener más información. para recuperar todos los valores de la tabla deleted. vea la sección Notas. vea Utilizar las tablas inserted y deleted. con excepciones. identidades y desencadenadores con NOT FOR REPLICATION. sql_statement Son las condiciones y acciones del desencadenador.SQL Server. es decir. Para obtener más información. Por ejemplo. . Un desencadenador está diseñado para comprobar o cambiar los datos en base a una instrucción de modificación o definición de datos. vea Controlar restricciones. INSERT o UPDATE. No se tiene acceso a los valores text. En un desencadenador DELETE. Importante: Los tipos de datos ntext. nvarchar(MAX) y varbinary(MAX) en las tablas inserted y deleted. Tanto los desencadenadores AFTER como INSTEAD OF admiten los datos varchar(MAX). especifica el método de enlace de un ensamblado con el desencadenador. Para obtener más información. Utilice nvarchar(max). . Si el nivel de compatibilidad es 80 o superior. La clase no puede ser anidada. < method_specifier > En el caso de un desencadenador CLR. ntext o image que admiten valores NULL. El método no puede utilizar argumentos y debe devolver void. si las columnas no permiten valores NULL. Cuando el nivel de compatibilidad es 65 o inferior. ntext o image mediante el desencadenador INSTEAD OF en tablas o vistas. Si la clase tiene un nombre calificado como espacio de nombres que utiliza '. combine la tabla inserted con la tabla de actualización original. se devuelven cadenas de longitud cero. vea Utilizar la función EVENTDATA. el nombre de la clase debe estar delimitado por delimitadores de tipo [ ] o " ". Evite su uso en nuevos trabajos de desarrollo y piense en modificar las aplicaciones que los usan actualmente. ntext e image de las tablas inserted y deleted. class_name debe ser un identificador de SQL Server válido y debe existir como una clase en el ensamblado con visibilidad de ensamblado. varchar(max) y varbinary(max) en su lugar. ntext o image en las tablas inserted y deleted si el nivel de compatibilidad es igual a 70. SQL Server no admite referencias de columnas text. text e image se quitarán en una versión futura de Microsoft SQL Server. se devuelven valores NULL para las columnas inserted o deleted text.' para separar las partes del espacio de nombres. Para recuperar el nuevo valor de un desencadenador INSERT o UPDATE. SQL Server permite actualizar las columnas text.Los desencadenadores DDL capturan información sobre el evento desencadenador mediante el uso de la función EVENTDATA (Transact-SQL). 16. pero estas referencias no se ejecutarán en una instancia de SQL Server a menos que la opción clr enabled esté habilitada mediante el uso de sp_configure.Nota: De manera predeterminada. Utilizar un desencadenador DML con un mensaje de aviso El siguiente desencadenador DML imprime un mensaje en el cliente cuando alguien intenta agregar o cambiar datos en la tabla Customer. 'TR') IS NOT NULL DROP TRIGGER Sales.reminder1 GO CREATE TRIGGER reminder1 ON Sales. UPDATE AS RAISERROR ('Notify Customer Relations'. es necesario contar con permiso ALTER sobre la tabla o vista en la que se crea el desencadenador.Customer AFTER INSERT. Utilizar un desencadenador DML con un mensaje de correo electrónico de aviso .reminder1'. Permisos Para crear un desencadenador DML. Copiar código USE AdventureWorks IF OBJECT_ID ('Sales. 10) GO B. la capacidad de SQL Server de ejecutar código CLR está desactivada. Ejemplos A. modificar y quitar objetos de bases de datos que hagan referencia a módulos de código administrados. Se puede crear. Para crear un desencadenador DDL con ámbito en el servidor (ON ALL SERVER) es necesario un permiso CONTROL SERVER sobre el servidor. Para crear un desencadenador DDL con ámbito en la base de datos (ON DATABASE) es necesario un permiso ALTER ANY DATABASE DDL TRIGGER en la base de datos actual. Para obtener la solvencia del proveedor.LowCredit'. se obtiene un mensaje y no se ejecuta la inserción. cualquier restricción de referencias cruzadas. reglas de empresa.' GO C.LowCredit GO CREATE TRIGGER LowCredit ON Purchasing. Copiar código USE AdventureWorks IF OBJECT_ID ('Sales. El desencadenador verifica que la solvencia del proveedor es satisfactoria cuando se intenta insertar un nuevo pedido de compra en la tabla PurchaseOrderHeader.reminder2'. en este caso.PurchaseOrderHeader AFTER INSERT AS . Copiar código IF OBJECT_ID ('Purchasing. 'Don''t forget to print a report for the sales force.'TR') IS NOT NULL DROP TRIGGER Sales. Si la solvencia no es satisfactoria. debe hacerse referencia a la tabla Vendor. Utilizar un desencadenador DML para exigir una regla de empresa entre las tablas PurchaseOrderHeader y Vendor Debido a que las restricciones CHECK sólo pueden hacer referencia a las columnas en que se han definido las restricciones de columna o de tabla.Este ejemplo envía un mensaje de correo electrónico a una persona especificada (MaryM) cuando cambia la tabla Customer. DELETE AS EXEC master. UPDATE. debe definirse como desencadenadores. En este ejemplo se crea un desencadenador DML.xp_sendmail 'MaryM'.'TR') IS NOT NULL DROP TRIGGER Purchasing..reminder2 GO CREATE TRIGGER reminder2 ON Sales.Customer AFTER INSERT. Creating a trigger on a nonexistent table.object_id.VendorID FROM Purchasing.definition FROM sys.sql_modules m ON t.VendorID IF @creditrating = 5 BEGIN RAISERROR ('This vendor''s credit rating is too low to accept new purchase orders. @vendorid int SELECT @creditrating = v. e.Creating a trigger on an existing table.type = 'TR' and t.info FROM HumanResources.parent_class = 1 GO -. CREATE TRIGGER trig1 on HumanResources.CreditRating.Vendor v on v.PurchaseOrderID = i. but with a .PurchaseOrderID JOIN Purchasing. x.Employee e INNER JOIN does_not_exist x ON e.VendorID = i. m.Here is the statement to actually see the text of the trigger. 16.BirthDate. DELETE AS SELECT e.trig1'. UPDATE. Copiar código USE AdventureWorks IF OBJECT_ID ('HumanResources.'TR') IS NOT NULL DROP TRIGGER HumanResources.DECLARE @creditrating tinyint.object_id WHERE t.EmployeeID = x.trig1 GO -.EmployeeID. Utilizar la resolución diferida de nombres El ejemplo siguiente crea dos desencadenadores DML para ilustrar la resolución diferida de nombres.name = 'trig1' AND t.'.object_id = m.triggers t INNER JOIN sys.xID GO -.PurchaseOrderHeader p INNER JOIN inserted i ON p. 1) ROLLBACK TRANSACTION END D. @vendorid = p. SELECT t.Employee AFTER INSERT. triggers WHERE parent_class = 0 AND name = 'safety') DROP TRIGGER safety ON DATABASE GO CREATE TRIGGER safety ON DATABASE FOR DROP_SYNONYM AS PRINT 'You must disable Trigger "safety" to drop synonyms!' ROLLBACK GO DROP TRIGGER safety ON DATABASE .type = 'TR' and t.trig2 GO CREATE TRIGGER trig2 ON HumanResources.trig2'. Utilizar un desencadenador DDL con ámbito en la base de datos En el ejemplo siguiente se utiliza un desencadenador DDL para impedir que se quiten sinónimos en una base de datos.Here is the statement to actually see the text of the trigger.nonexistent -.name = 'trig2' AND t.sql_modules m ON t. Copiar código USE AdventureWorks IF EXISTS (SELECT * FROM sys.triggers t INNER JOIN sys.Employee AFTER INSERT. USE AdventureWorks IF OBJECT_ID ('HumanResources.object_id = m. SELECT t.Employee GO -.object_id WHERE t.'TR') IS NOT NULL DROP TRIGGER HumanResources. UPDATE AS DECLARE @fax varchar(12) SELECT @fax = 'AltPhone' FROM HumanResources.parent_class = 1 GO E.object_id.column. m.definition FROM sys. Copiar código IF EXISTS (SELECT * FROM sys.GO E.trigger_events para determinar qué eventos de lenguaje Transact-SQL hacen que se active el desencadenador safety.* FROM sys.triggers AS T ON T.value('(/EVENT_INSTANCE/TSQLCommand/Comman dText)[1]'. y se utiliza la función EVENTDATA para recuperar el texto de la instrucción Transact-SQL correspondiente.trigger_events AS TE JOIN sys.object_id . Copiar código SELECT TE. ALTER LOGIN o DROP LOGIN en la instancia actual del servidor. safety se ha creado en un ejemplo anterior.'nvarchar(max)') GO DROP TRIGGER ddl_trig_login ON ALL SERVER GO G.object_id = TE.triggers y sys. Ver los eventos que hacen que se active un desencadenador En el ejemplo siguiente se efectúa una consulta en las vistas de catálogo sys. Utilizar un desencadenador DDL con ámbito en el servidor En el ejemplo siguiente se utiliza un desencadenador DDL para imprimir un mensaje si se produce un evento CREATE LOGIN.server_triggers WHERE name = 'ddl_trig_login') DROP TRIGGER ddl_trig_login ON ALL SERVER GO CREATE TRIGGER ddl_trig_login ON ALL SERVER FOR DDL_LOGIN_EVENTS AS PRINT 'Login Event Issued.' SELECT EVENTDATA(). identidades y desencadenadores con NOT FOR REPLICATION Utilizar tipos de datos de valores grandes Ayuda e información .name = 'safety' GO Vea también Referencia ALTER TABLE (Transact-SQL) ALTER TRIGGER (Transact-SQL) COLUMNS_UPDATED (Transact-SQL) CREATE TABLE (Transact-SQL) DROP TRIGGER (Transact-SQL) ENABLE TRIGGER (Transact-SQL) DISABLE TRIGGER (Transact-SQL) TRIGGER_NESTLEVEL (Transact-SQL) sp_depends (Transact-SQL) sys.sql_modules (Transact-SQL) sys.server_triggers sys.assembly_modules (Transact-SQL) sys.server_trigger_events sys.WHERE T.sql_dependencies (Transact-SQL) sp_help (Transact-SQL) sp_helptrigger (Transact-SQL) sp_helptext (Transact-SQL) sp_rename (Transact-SQL) sp_settriggerorder (Transact-SQL) UPDATE() (Transact-SQL) sys.parent_class = 0 AND T.trigger_events (Transact-SQL) sys.triggers (Transact-SQL) sys.server_sql_modules sys.server_assembly_modules (Transact-SQL) Otros recursos Crear procedimientos almacenados (motor de base de datos) Programar desencadenadores CLR Usar identificadores como nombres de objeto Obtener información acerca de los desencadenadores DML Obtener información acerca de los desencadenadores DDL Controlar restricciones. Realizar una acción alternativa si se produce una condición de error. un desencadenador INSTEAD OF actualiza dos tablas base desde una vista. Además. No procesar una parte de un lote y registrar las filas que presentan problemas. • Nota: No se pueden definir desencadenadores INSTEAD OF DELETE ni INSTEAD OF UPDATE en tablas que contengan una clave externa definida mediante una acción en cascada DELETE o UPDATE.Vistas-desencadenadores La principal ventaja de los desencadenadores INSTEAD OF es que permiten a las vistas que no serían actualizables admitir actualizaciones. al mismo tiempo. La codificación de esta lógica como parte de un desencadenador INSTEAD OF evita que todas las aplicaciones que obtienen acceso a los datos tengan que volver a implementar la lógica. Un desencadenador INSTEAD OF puede realizar acciones como: • • Omitir partes de un lote. se muestran los siguientes enfoques de control de errores: Las inserciones duplicadas de la tabla Person se omiten y la información de la inserción se registra en la tabla PersonDuplicates. • . aceptar otras partes del mismo. actualizaciones y eliminaciones que hagan referencia a datos de más de una tabla. Las vistas que contengan varias tablas base deben utilizar un desencadenador INSTEAD OF para permitir inserciones. Ejemplo En la siguiente secuencia de instrucciones Transact-SQL. Otra ventaja de los desencadenadores INSTEAD OF es que permiten codificar la lógica para rechazar partes de un lote y. . SSN char(11) UNIQUE. Department nvarchar(10).SSN = E. CONSTRAINT FKEmpPer FOREIGN KEY (SSN) REFERENCES Person (SSN) ) Esta vista presenta los datos importantes de las dos tablas acerca de una persona: Copiar código CREATE VIEW Employee AS SELECT P. EmployeeID. Salary money. Address nvarchar(100). Birthdate datetime ) CREATE TABLE EmployeeTable ( EmployeeID int PRIMARY KEY. • Las instrucciones Transact-SQL crean dos tablas base. Name. Name nvarchar(100). Birthdate. Department. Las siguientes tablas separan la información personal de la empresarial y constituyen las tablas base de la vista: Copiar código CREATE TABLE Person ( SSN char(11) PRIMARY KEY. una vista. el nombre del usuario que intentó realizar la inserción y la hora de la inserción.SSN Puede registrar intentos de insertar filas con números de seguridad social duplicados.SSN as SSN. Salary FROM Person P. una tabla para registrar errores y el desencadenador INSTEAD OF en la vista.Las inserciones de duplicados en EmployeeTable se convierten en una instrucción UPDATE que recupera la información actual de la tabla EmployeeTable sin generar una infracción de clave duplicada. La tabla PersonDuplicates registra los valores insertados. Address. EmployeeTable E WHERE P. IF (NOT EXISTS (SELECT E.Address. InsertSNAME nchar(100).SSN)) INSERT INTO Person SELECT SSN. inserted WHERE E.Name.Check for duplicate Employee. do an INSERT. IF (NOT EXISTS (SELECT P. Birthdate datetime. Department. INSERT INTO PersonDuplicates SELECT SSN. Address nvarchar(100). WhenInserted datetime ) El desencadenador INSTEAD OF inserta filas en varias tablas base desde una única vista. If no there is duplicate.SUSER_SNAME().GETDATE() FROM inserted -. If there is no duplicate. do an insert. Name nvarchar(100).SSN FROM Person P.Birthdate FROM inserted ELSE -.SSN FROM EmployeeTable E.Address.SSN. Salary FROM inserted .Birthdate.SSN = inserted.SSN)) INSERT INTO EmployeeTable SELECT EmployeeID. Las filas duplicadas de EmployeeTable se cambian por instrucciones de actualización. Copiar código CREATE TRIGGER IO_Trig_INS_Employee ON Employee INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON -. Los intentos de insertar filas con números de seguridad social duplicados se registran en la tabla PersonDuplicates.Check for duplicate Person.Log an attempt to insert duplicate Person row in PersonDuplicates table.SSN = I. inserted I WHERE P.Name.Copiar código CREATE TABLE PersonDuplicates ( SSN char(11). Salary FROM EmployeeTable E. change to UPDATE so that there will not --be a duplicate key violation error. Department = I.ELSE --If there is a duplicate. inserted I WHERE E.SSN END .SSN = I.Department. UPDATE EmployeeTable SET EmployeeID = I.EmployeeID. Salary = I.