SQL Server 2005: T-SQL to temporarily disable a trigger

前端 未结 7 1116
太阳男子
太阳男子 2020-12-08 04:33

Is it possible to disable a trigger for a batch of commands and then enable it when the batch is done?

I\'m sure I could drop the trigger and re-add it but I was won

7条回答
  •  感情败类
    2020-12-08 04:54

    Another approach is to effectively disable the trigger without actually disabling it, using an additional state variable that is incorporated into the trigger.

    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
    

    For the state variable one could read some type of lock control record in a table (best if limited to the context of the current session), use CONTEXT_INFO(), or use the presence of a particular temp table name (which is already session scope limited):

    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
    

    Then to disable all triggers:

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

    A potentially major downside is that the trigger is permanently slowed down depending on the complexity of accessing of the state variable.

    Edit: Adding a reference to this amazingly similar 2008 post by Samuel Vanga.

提交回复
热议问题