SQL Server 2005: T-SQL для временного отключения триггера


44

Можно ли отключить триггер для партии команд, а затем включить его, когда пакет выполнен?

Я уверен, что могу сбросить курок и снова добавить его, но мне было интересно, есть ли другой способ.

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

http://msdn.microsoft.com/en-us/library/ms189748(SQL.90).aspx

с последующим обратным:

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

http://msdn.microsoft.com/en-us/library/ms182706(SQL.90).aspx

  0

Спасибо! Я думаю, что моя слабость SQL Server 2005 слишком хорошо проявляется на этом сайте. 23 сен. 082008-09-23 20:15:46

  0

Не беспокойтесь; быть DBA в течение длительного времени, и эти вещи становятся автоматическими :) 23 сен. 082008-09-23 20:16:41

  0

т. е. если вы используете опцию для изменения триггера, а скрипт содержит 'ALTER TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' then you необходимо 'DISABLE TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' и 'ENABLE TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' 22 сен. 152015-09-22 14:45:41

  0

ПРИМЕЧАНИЕ - Я получаю сообщение об ошибке 'Неправильный синтаксис рядом с «DISABLE». если я не помещаю ';' между 'PRINT 'Some message'; DISABLE TRIGGER [dbo] ..... ' 23 сен. 152015-09-23 15:22:06


15

Однако, это почти всегда плохая идея, чтобы сделать это. Вы будете возиться с целостностью базы данных. Не делайте этого, не учитывая разветвлений и проверки с помощью dbas, если они у вас есть.

Если вы следуете за кодом Мэтта, обязательно забудьте снова включить спусковой крючок. И помните, что триггер отключен для всех, кто вставляет, обновляет или удаляет из таблицы во время его отключения, а не только для вашего процесса, поэтому, если это необходимо сделать, сделайте это в часы, когда база данных будет наименее активной (и предпочтительно в однопользовательском режиме).

Если вам нужно сделать это, чтобы импортировать большой объем данных, тогда подумайте, что объемная вставка не запускает триггеры. Но тогда ваш процесс после объемной вставки должен будет устранить любые проблемы с целостностью данных, которые вы вводите или запускаете триггеры.

  0

Отличные очки. Причина, по которой я нуждался в этом, заключалась в копировании данных из производственной среды в тестовую среду, некоторые AKs сбрасывались триггером, но соответствующие столбцы в другой таблице не соответствовали требованиям. 23 сен. 082008-09-23 21:12:18


30

Иногда, чтобы заполнить пустую базу данных из внешнего источника данных или отладить проблему в базе данных, мне нужно отключить ВСЕ триггеры и ограничения. Для этого я использую следующий код:

Чтобы отключить все ограничения и триггеры:

sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all" 
sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all" 

Чтобы включить все ограничения и триггеры:

exec sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all" 
sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? ENABLE TRIGGER all" 

Я обнаружил, что решение некоторое время назад на SQLServerCentral, но необходимо было модифицировать часть ограничений включения, так как оригинал не работал полностью


9

Чтобы продлить ответ Мэтта, вот пример, приведенный на MSDN.

USE AdventureWorks; 
GO 
DISABLE TRIGGER Person.uAddress ON Person.Address; 
GO 
ENABLE Trigger Person.uAddress ON Person.Address; 
GO 

4

Другой подход заключается в эффективно отключить на спусковой крючок без фактического отключения его, используя дополнительное переменное состояние, которая включена в триггер.

create trigger [SomeSchema].[SomeTableIsEditableTrigger] ON [SomeSchema].[SomeTable] 
for insert, update, delete 
as 
declare 
    @isTableTriggerEnabled bit; 

exec usp_IsTableTriggerEnabled -- Have to use USP instead of UFN for access to #temp 
    @pTriggerProcedureIdOpt = @@procid,  
    @poIsTableTriggerEnabled = @isTableTriggerEnabled out; 

if (@isTableTriggerEnabled = 0) 
    return; 

-- Rest of existing trigger 
go 

Для переменной состояния можно прочитать некоторый тип блокировки записи управления в таблице (лучше всего, если ограничиваться контексте текущей сессии), используйте CONTEXT_INFO(), или использовать присутствие определенной темп таблицы имя (которое уже сессия Ограничивается):

create proc [usp_IsTableTriggerEnabled] 
    @pTriggerProcedureIdOpt bigint   = null, -- Either provide this 
    @pTableNameOpt   varchar(300) = null, -- or this 
    @poIsTableTriggerEnabled bit    = null out 
begin 

    set @poIsTableTriggerEnabled = 1; -- default return value (ensure not null) 

    -- Allow a particular session to disable all triggers (since local 
    -- temp tables are session scope limited). 
    -- 
    if (object_id('tempdb..#Common_DisableTableTriggers') is not null) 
    begin 
     set @poIsTableTriggerEnabled = 0; 
     return; 
    end 

    -- Resolve table name if given trigger procedure id instead of table name. 
    -- Google: "How to get the table name in the trigger definition" 
    -- 
    set @pTableNameOpt = coalesce(
     @pTableNameOpt, 
     (select object_schema_name(parent_id) + '.' + object_name(parent_id) as tablename 
      from sys.triggers 
      where object_id = @pTriggerProcedureIdOpt) 
    ); 

    -- Else decide based on logic involving @pTableNameOpt and possibly current session 
end 

Затем, чтобы отключить все триггеры:

select 1 as A into #Common_DisableTableTriggers; 
-- do work 
drop table #Common_DisableTableTriggers; -- or close connection 

потенциально основным недостатком является то, что триггер постоянно Слоу d down в зависимости от сложности доступа к переменной состояния.

Редактировать: Добавление ссылки на этот удивительно похожий 2008 post by Samuel Vanga.


2
ALTER TABLE table_name DISABLE TRIGGER TRIGGER_NAME 
-- Here your SQL query 
ALTER TABLE table_name ENABLE TRIGGER TRIGGER_NAME 

2

Не лучший ответ для пакетного программирования, но и для других, находящих на этот вопрос в поисках быстрый и простой способ, чтобы временно отключить триггер, это может быть сделано в SQL Server Management Studio.

  1. развернуть папку Триггеры на столе
  2. правой кнопкой мыши на спусковой крючок
  3. отключить

enter image description here

Выполните тот же процесс для повторного включения.