ver usar una trigger tabla siguientes puede los las instrucciones excepto ejemplos disparador disabled disable sql-server tsql triggers

sql-server - una - un disparador se puede usar en las siguientes instrucciones dml excepto



¿Hay alguna forma de desactivar un desencadenador de SQL Server solo para un determinado ámbito de ejecución? (11)

Acabo de enfrentar el mismo problema y se me ocurrió la siguiente solución, que funciona para mí.

  1. Cree una tabla de base de datos permanente que contenga un registro para cada activador que desee desactivar (por ejemplo, refTriggerManager); cada fila contiene el nombre del disparador (por ejemplo, strTriggerName = ''myTrigger'') y un indicador de bit (por ejemplo, blnDisabled, por defecto a 0).

  2. Al comienzo del cuerpo del disparador, busque strTriggerName = ''myTrigger'' en refTriggerManager. Si blnDisabled = 1, regrese sin ejecutar el resto del código de activación, de lo contrario continúe el código de activación hasta su finalización.

  3. En el proceso almacenado en el que desea deshabilitar el desencadenador, haga lo siguiente:

COMIENZA LA TRANSACCIÓN

ACTUALIZACIÓN refTriggerManager SET blnDisabled = 1 WHERE strTriggerName = ''myTrigger''

/ * ACTUALIZA la tabla que posee ''myTrigger'' pero que deseas desactivar. Dado que refTriggerManager.blnDisabled = 1, ''myTrigger'' regresa sin ejecutar su código. * /

ACTUALIZACIÓN refTriggerManager SET blnDisabled = 0 WHERE triggerName = ''myTrigger''

/ * Código de ACTUALIZACIÓN final opcional que desencadena el desencadenador. Como refTriggerManager.blnDisabled = 0, ''myTrigger'' se ejecuta en su totalidad. * /

COMPROMETER LA TRANSACCIÓN

Todo esto tiene lugar dentro de una transacción, por lo que está aislado del mundo exterior y no afectará a otras ACTUALIZACIONES en la tabla objetivo.

¿Alguien ve algún problema con este enfoque?

Cuenta

En SQL Server 2005, ¿hay alguna manera de que un desencadenante descubra qué objeto es responsable de disparar el desencadenador? Me gustaría utilizar esto para desactivar el desencadenante de un prodecure almacenado.

¿Hay alguna otra forma de desactivar el activador solo para la transacción actual? Podría usar el siguiente código, pero si no me equivoco, también afectaría las transacciones concurrentes, lo que sería algo malo.

DISABLE TRIGGER { [ schema_name . ] trigger_name [ ,...n ] | ALL } ON { object_name | DATABASE | ALL SERVER } [ ; ] ENABLE TRIGGER { [ schema_name . ] trigger_name [ ,...n ] | ALL } ON { object_name | DATABASE | ALL SERVER } [ ; ]

Si es posible, me gustaría evitar la técnica de tener un campo "NoTrigger" en mi tabla y hacer un NoTrigger = null , porque me gustaría mantener la tabla lo más pequeña posible.

La razón por la que me gustaría evitar el desencadenador es porque contiene lógica que es importante para las actualizaciones manuales de la tabla, pero mi procedimiento almacenado se encargará de esta lógica. Debido a que este será un procedimiento muy utilizado, quiero que sea rápido.

Los activadores imponen una sobrecarga adicional en el servidor porque inician una transacción implícita. Tan pronto como se ejecuta un disparador, se inicia una nueva transacción implícita, y cualquier recuperación de datos dentro de una transacción mantendrá bloqueos en las tablas afectadas.

De: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1170220,00.html#trigger


Acabo de ver este artículo destacado recientemente en el boletín informativo de SQL Server Central y parece ofrecer una manera que puede resultarle útil utilizando Context_Info en la conexión:

http://www.mssqltips.com/tip.asp?tip=1591

EDIT por Terrapin:

El enlace de arriba incluye el siguiente código:

USE AdventureWorks; GO -- creating the table in AdventureWorks database IF OBJECT_ID(''dbo.Table1'') IS NOT NULL DROP TABLE dbo.Table1 GO CREATE TABLE dbo.Table1(ID INT) GO -- Creating a trigger CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE AS DECLARE @Cinfo VARBINARY(128) SELECT @Cinfo = Context_Info() IF @Cinfo = 0x55555 RETURN PRINT ''Trigger Executed'' -- Actual code goes here -- For simplicity, I did not include any code GO

Si desea evitar que se ejecute el desencadenador, puede hacer lo siguiente:

SET Context_Info 0x55555 INSERT dbo.Table1 VALUES(100)



Como usted indica que el desencadenador contiene lógica para manejar todas las actualizaciones, incluso las manuales, entonces debería ser allí donde resida la lógica. El ejemplo que mencionas, en el que un procedimiento almacenado "se encargará de esta lógica" implica un código duplicado. Además, si quiere estar seguro de que cada instrucción UPDATE tiene aplicada esta lógica independientemente del autor, entonces el desencadenador es el lugar adecuado. ¿Qué sucede cuando alguien crea un procedimiento pero olvida duplicar la lógica una vez más? ¿Qué sucede cuando es el momento de modificar la lógica?


Considere volver a escribir el desencadenador para mejorar el rendimiento si el rendimiento es el problema.


Me quedé boquiabierto con esto. Por un lado, soy muy antiactivador, sobre todo porque es un lugar más en el que puedo buscar la ejecución del código en mi tabla, además de los motivos indicados en el artículo vinculado en la publicación de la pregunta.

Por otro lado, si tiene lógica para aplicar reglas comerciales estables e inmutables o acciones de tabla cruzada (como mantener una tabla de historial), entonces sería más seguro colocar esto en un desencadenante para que los autores de procedimientos y programadores no necesiten lidiar con eso, simplemente funciona.

Por lo tanto, mi recomendación es poner la lógica necesaria en su desencadenante en lugar de en este proceso que, inevitablemente crecerá a varios procesos con la misma exención.


No deshabilite el disparador. Tiene razón de que se deshabilitará para cualquier transacción simultánea.

¿Por qué quieres desactivar el gatillo? ¿Qué hace? ¿Por qué está causando el gatillo un problema? Por lo general, es una mala idea desactivar un tigger desde una perspectiva de integridad de datos.


Si su desencadenante está causando problemas de rendimiento en la aplicación, entonces el mejor enfoque es eliminar todas las actualizaciones manuales de la tabla y exigir que todas las actualizaciones pasen por los procedimientos almacenados de inserción / actualización que contienen la lógica de actualización correcta. Entonces puedes quitar el gatillo por completo.

Sugiero que se denieguen los permisos de actualización de tabla si nada funciona.

Esto también resuelve el problema del código duplicado. Duplicar el código en la actualización SP y en el desencadenante es una violación de los buenos principios de ingeniería de software y será un problema de mantenimiento.


Estoy de acuerdo con algunas otras respuestas. No deshabilite el disparador.

Esta es pura opinión, pero evito factores desencadenantes como la peste. He encontrado muy pocos casos en los que se haya utilizado un desencadenador para aplicar las reglas de la base de datos. Hay casos obvios en mi experiencia, y solo tengo mi experiencia para hacer esta afirmación. Normalmente he visto desencadenantes utilizados para insertar algunos datos relacionales (lo que se debe hacer desde la lógica comercial), insertar datos en la tabla de informes, es decir, desnormalizar los datos (que se pueden hacer con un proceso fuera de la transacción) o transformar los datos de alguna manera.

Existen usos legítimos para los factores desencadenantes, pero creo que en la programación empresarial cotidiana son pocos y distantes. Puede que esto no ayude en su problema actual, pero podría considerar eliminar el gatillo por completo y realizar el trabajo que el activador está haciendo de alguna otra manera.


No estoy seguro si esta es una buena idea, pero parece funcionar para mí. La transacción debe evitar las inserciones en la tabla de otros procesos mientras el activador está deshabilitado.

IF OBJECT_ID(''dbo.TriggerTest'') IS NOT NULL DROP PROCEDURE dbo.TriggerTest GO CREATE PROCEDURE [dbo].[TriggerTest] AS BEGIN TRANSACTION trnInsertTable1s ; DISABLE TRIGGER trg_tblTable1_IU ON tblTable1 ; BEGIN -- Procedure Code PRINT ''@@trancount'' PRINT @@TRANCOUNT -- Do Stuff END -- Procedure Code ; ENABLE TRIGGER trg_tblTable1_IU ON tblTable1 IF @@ERROR <> 0 ROLLBACK TRANSACTION ELSE COMMIT TRANSACTION


puede usar la función '' Exec '' para desactivar y habilitar desencadenadores desde un procedimiento almacenado. Ejemplo: EXEC (''ENABLE TRIGGER dbo.TriggerName on dbo.TriggeredTable'')