update tutorial trigger inserted example ejemplos create after sql-server database-design triggers

sql server - tutorial - Activadores de base de datos



trigger sql server update (12)

Los desencadenantes generalmente se usan incorrectamente, introducen errores y por lo tanto deben evitarse. Nunca diseñe un disparador para hacer una comprobación de restricción de integridad que cruce las filas en una tabla (por ejemplo, "el salario promedio por departamento no puede exceder X").

Tom Kyte , vicepresidente de Oracle, ha indicado que preferiría eliminar los desencadenantes como una característica de la base de datos de Oracle debido a su papel frecuente en los errores. Él sabe que es solo un sueño, y los desencadenantes llegaron para quedarse, pero si pudiera eliminar los desencadenantes de Oracle, lo haría (junto con la cláusula WHEN OTHERS y las transacciones autónomas).

¿Pueden los desencadenantes ser utilizados correctamente? Absolutamente.

El problema es que no se usan correctamente en tantos casos que estaría dispuesto a renunciar a cualquier beneficio percibido solo para deshacerse de los abusos (y errores) causados ​​por ellos. - Tom Kyte

En el pasado, nunca me han gustado los triggers en las tablas de la base de datos. Para mí siempre representaron algo de "magia" que iba a suceder en el lado de la base de datos, muy lejos del control de mi código de aplicación. También quería limitar la cantidad de trabajo que el DB tenía que hacer, ya que generalmente es un recurso compartido y siempre asumí que los disparadores podrían llegar a ser costosos en escenarios de carga alta.

Dicho esto, he encontrado un par de casos en los que los desencadenantes tienen sentido usarlos (al menos en mi opinión tienen sentido). Recientemente, sin embargo, me encontré en una situación en la que a veces podría necesitar "puentear" el gatillo. Me sentí realmente culpable por tener que buscar la forma de hacerlo, y todavía creo que un mejor diseño de la base de datos aliviará la necesidad de evitarlo. Desafortunadamente, este DB es utilizado por múltiples aplicaciones, algunas de las cuales son mantenidas por un equipo de desarrollo muy poco cooperativo que gritaba sobre los cambios de esquema, por lo que estaba atascado.

¿Cuál es el consenso general sobre desencadenantes? Amor em? ¿Los odio? ¿Crees que sirven un propósito en algunos escenarios? ¿Crees que tener una necesidad de puentear un gatillo significa que estás "haciendo las cosas mal"?


La regla general es: no usar disparadores. Como se mencionó anteriormente, agregan sobrecarga y complejidad que pueden evitarse fácilmente moviendo la lógica fuera de la capa DB.

Además, en MS SQL Server, los disparos se disparan una vez por comando sql, y no por fila. Por ejemplo, la siguiente instrucción sql ejecutará el desencadenante solo una vez.

UPDATE tblUsers SET Age = 11 WHERE State = ''NY''

Muchas personas, incluyéndome a mí, tenían la impresión de que se disparaban los factores desencadenantes en cada fila, pero este no es el caso. Si tiene una instrucción sql como la anterior que puede cambiar los datos en más de una fila, puede incluir un cursor para actualizar todos los registros afectados por el desencadenador. Puedes ver cómo esto puede complicarse muy rápidamente.


En cuanto a la reducción de la cantidad de trabajo: las bases de datos son increíblemente eficientes cuando no tienen que lidiar con el mundo exterior; estarías realmente sorprendido de cuánto incluso el cambio de proceso perjudica el rendimiento. Esa es otra ventaja de los procedimientos almacenados: en lugar de una docena de llamadas a la base de datos (y todas las visitas de ida y vuelta asociadas), hay una.

esto es un poco fuera de tema, pero también debes ser consciente de que solo estás viendo esto desde un potencial positivo.

Agrupar cosas en un único proceso almacenado está bien, pero ¿qué sucede cuando algo sale mal? Supongamos que tiene 5 pasos y el primer paso falla, ¿qué ocurre con los otros pasos? Necesita agregar un montón de lógica para atender esa situación. Una vez que empiezas a hacer eso, pierdes los beneficios del procedimiento almacenado en ese escenario.


Honestamente, la única vez que uso disparadores para simular un índice único que tiene permitido tener NULL que no cuenta para la singularidad.


Me encuentro pasando por alto los factores desencadenantes al hacer importaciones masivas de datos. Creo que está justificado en tales circunstancias.

Sin embargo, si termina pasando por alto los factores desencadenantes, es probable que necesite echar otro vistazo a lo que los puso allí en primer lugar.

En general, votaría por "sirven para un propósito en algunos escenarios". Siempre estoy nervioso por las implicaciones de rendimiento.


No soy fanático, personalmente. Los usaré, pero solo cuando descubra un cuello de botella en el código que se puede borrar moviendo acciones a un disparador. En general, prefiero la simplicidad y una forma de mantener las cosas simples es mantener la lógica en un solo lugar: la aplicación. También trabajé en trabajos donde el acceso es muy compartimentado. En esos entornos, cuanto más código agregue, más personas tendré que contratar, incluso para las soluciones más simples.


Primero usé desencadenantes hace un par de semanas. Cambiamos a través de un servidor de producción de SQL 2000 a SQL 2005 y encontramos que los controladores se comportaban de manera diferente con los campos NText (que almacenaban un documento XML grande) y descartaban el último byte. Usé un disparador como una solución temporal para agregar un byte ficticio adicional (un espacio) al final de los datos, resolviendo nuestro problema hasta que se pudiera implementar una solución adecuada.

Aparte de este caso especial y temporal, diría que los evitaría, ya que ocultan lo que está sucediendo, y la función que proporcionan debe ser manejada explícitamente por el desarrollador, en lugar de como una magia oculta.


Trabajo con aplicaciones web y winforms en c # y ODIO los desencadenantes con pasión. Nunca me he encontrado con una situación en la que pudiera justificar el uso de un desencadenante para mover esa lógica a la capa empresarial de la aplicación y replicar allí la lógica de activación.

No hago ningún trabajo de tipo DTS ni nada de eso, por lo que podría haber algunos casos de uso para usar el desencadenador allí, pero si alguien en alguno de mis equipos dice que podrían querer utilizar un activador, es mejor que hayan preparado bien sus argumentos. porque me niego a esperar y dejar que los desencadenantes se agreguen a cualquier base de datos en la que estoy trabajando.

Algunas razones por las que no me gustan los factores desencadenantes:

  • Mueven la lógica a la base de datos. Una vez que comienzas a hacer eso, estás pidiendo un mundo de dolor porque pierdes tu depuración, tu seguridad en tiempo de compilación, tu flujo lógico. Es todo cuesta abajo.
  • La lógica que implementan no es fácilmente visible para nadie.
  • No todos los motores de base de datos admiten desencadenantes, por lo que su solución crea dependencias en los motores de base de datos.

Estoy seguro de que podría pensar en más razones fuera de mi cabeza, pero esas solo son suficientes para que yo no use desencadenantes.


Ventilador total,

pero realmente tiene que usarlo con moderación cuando,

  • Necesitamos mantener la consistencia (especialmente cuando las tablas de dimensiones se usan en un almacén y necesitamos relacionar los datos en la tabla de hechos con su dimensión adecuada. En algún momento, la fila correcta en la tabla de dimensiones puede ser muy costosa de computar, por lo que desea la clave para escribir directamente en la tabla de hechos, una buena manera de mantener esa "relación" es con el disparador.

  • Necesidad de registrar cambios (en una tabla de auditoría, por ejemplo, es útil saber qué @@ usuario hizo el cambio y cuándo ocurrió)

Algunos RDBMS como sql server 2005 también le proporcionan activadores en las sentencias CREATE / ALTER / DROP (para que pueda saber quién creó qué tabla, cuándo, quitó qué columna, cuándo, etc.)

Honestamente, usando desencadenadores en esos 3 escenarios, no veo por qué alguna vez necesitarías "deshabilitarlos".


"Nunca diseñar un disparador para hacer una comprobación de restricción de integridad que cruce filas en una tabla" - No puedo estar de acuerdo. La pregunta está etiquetada ''SQL Server'' y las cláusulas CHECK constraints ''en SQL Server no pueden contener una subconsulta; peor aún, la implementación parece tener una suposición ''codificada'' de que un CHECK involucrará solo una fila, por lo que usar una función no es confiable. Entonces, si necesito una restricción que legítimamente involucre más de una fila, y un buen ejemplo aquí es la clave primaria secuenciada en una tabla temporal clásica de "tiempo válido" en la que necesito evitar períodos superpuestos para la misma entidad: cómo puedo Lo hago sin un disparador? Recuerde que esta es una clave principal, algo para garantizar que tengo integridad de datos, por lo que su aplicación en cualquier lugar que no sea el DBMS está fuera de cuestión. Hasta que las restricciones CHECK obtengan subconsultas, no veo una alternativa al uso de desencadenantes para ciertos tipos de restricciones de integridad.


Piense en una base de datos como un gran objeto grande: después de cada llamada, debería estar en un estado lógicamente consistente.

Las bases de datos se exponen a través de tablas, y mantener tablas y filas consistentes se puede hacer con desencadenantes. Otra forma de mantenerlos constantes es no permitir el acceso directo a las tablas, y solo permitirlo a través de procedimientos almacenados y vistas.

La desventaja de los factores desencadenantes es que cualquier acción puede invocarlos; esto también es una fortaleza: nadie va a arruinar la integridad del sistema por incompetencia.

Como contrapunto, permitir el acceso a una base de datos solo a través de procedimientos almacenados y vistas aún permite el acceso de permisos de puerta trasera. Se confía en que los usuarios con permisos suficientes no rompan la integridad de la base de datos, todos los demás usan procedimientos almacenados.

En cuanto a la reducción de la cantidad de trabajo: las bases de datos son increíblemente eficientes cuando no tienen que lidiar con el mundo exterior; estarías realmente sorprendido de cuánto incluso el cambio de proceso perjudica el rendimiento. Esa es otra ventaja de los procedimientos almacenados: en lugar de una docena de llamadas a la base de datos (y todas las visitas de ida y vuelta asociadas), hay una.

Agrupar cosas en un único proceso almacenado está bien, pero ¿qué sucede cuando algo sale mal? Supongamos que tiene 5 pasos y el primer paso falla, ¿qué ocurre con los otros pasos? Necesita agregar un montón de lógica para atender esa situación. Una vez que empiezas a hacer eso, pierdes los beneficios del procedimiento almacenado en ese escenario.

La lógica empresarial tiene que ir a algún lado, y hay muchas reglas implícitas de dominio incrustadas en el diseño de una base de datos: las relaciones, restricciones, etc. son un intento de codificar las reglas comerciales diciendo, por ejemplo, que un usuario solo puede tener una contraseña. Dado que ha empezado a implementar las reglas de negocio en el servidor de la base de datos teniendo estas relaciones, etc., ¿dónde dibuja la línea? ¿Cuándo la base de datos renuncia a la responsabilidad de la integridad de los datos y comienza a confiar en las aplicaciones de las llamadas y en los usuarios de la base de datos para hacerlo bien? Los procedimientos almacenados con estas reglas integradas en ellos pueden llevar mucho poder político a las manos de los DBA. Se trata de cuántos niveles van a existir en su arquitectura de n niveles; si hay una capa de presentación, negocios y datos, ¿dónde se encuentra la separación entre el negocio y los datos? ¿Qué valor agregado agrega la capa empresarial? ¿Ejecutará la capa empresarial en el servidor de la base de datos como procedimientos almacenados?

Sí, creo que tener que eludir un desencadenador significa que estás "haciéndolo mal"; en este caso, un gatillo no es para ti.


Los desencadenantes pueden ser muy útiles. También pueden ser muy peligrosos. Creo que están bien para las tareas de limpieza de la casa como rellenar datos de auditoría (creados por, fecha de modificación, etc.) y en algunas bases de datos se pueden utilizar para la integridad referencial.

Pero no soy un gran admirador de poner mucha lógica de negocios en ellos. Esto puede hacer que el soporte sea problemático porque:

  • es una capa extra de código para investigar
  • a veces, como aprendió el OP, cuando necesita corregir datos, el desencadenador puede estar haciendo cosas con la suposición de que el cambio de datos es siempre a través de una directiva de aplicación y no de un desarrollador o DBA que resuelve un problema, o incluso de un diferente aplicación

En cuanto a tener que eludir un disparador para hacer algo, podría significar que estás haciendo algo mal, o podría significar que el gatillo está haciendo algo mal.

La regla general que me gusta usar con los factores desencadenantes es mantenerlos livianos, rápidos, simples y lo menos invasivos posible.