SQL Server 2005: T-SQL per disabilitare temporaneamente un trigger


44

È possibile disabilitare un trigger per un batch di comandi e quindi abilitarlo quando viene eseguito il batch?

Sono sicuro di poter rilasciare il grilletto e riaggiungerlo ma mi chiedevo se c'era un altro modo.

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

seguita per l'inverso:

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

Grazie! Penso che la mia ingenuità di SQL Server 2005 si stia mostrando troppo bene su questo sito. 23 set. 082008-09-23 20:15:46

  0

Nessun problema; essere un DBA per molto tempo e queste cose diventano automatiche :) 23 set. 082008-09-23 20:16:41

  0

cioè se si usa l'opzione per modificare un trigger e lo script contiene 'ALTER TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' allora tu bisogno di 'DISABLE TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' e 'ENABLE TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWhatever]' 22 set. 152015-09-22 14:45:41

  0

NOTA - Ottengo un errore 'Sintassi errata vicino a 'DISABLE'. ' a meno che non metta un ';' tra 'PRINT 'Some message'; DISABILITA TRIGGER [dbo] ..... ' 23 set. 152015-09-23 15:22:06


15

Tuttavia, è quasi sempre una cattiva idea di fare questo. Scoprirai dell'integrità del database. Non farlo senza considerare le ramificazioni e controllare con il dbas se li hai.

Se segui il codice di Matt assicurati di ricordare di riaccendere il grilletto. E ricorda che il trigger è disabilitato per tutti gli inserimenti, l'aggiornamento o l'eliminazione dalla tabella mentre è disattivato, non solo per il tuo processo, quindi se deve essere fatto, fallo durante le ore in cui il database è meno attivo (e preferibilmente in modalità utente singolo).

Se è necessario eseguire questa operazione per importare una grande quantità di dati, considerare che l'inserimento in blocco non attiva i trigger. Ma poi il tuo processo dopo l'inserimento di massa dovrà risolvere eventuali problemi di integrità dei dati che introduci o inneschi i trigger.

  0

Grandi punti. Il motivo per cui avevo bisogno di questo era quando copiavo i dati da un ambiente di produzione in un ambiente di test alcuni AK erano stati ripristinati dal trigger ma le colonne correlate in un'altra tabella non stavano seguendo l'esempio. 23 set. 082008-09-23 21:12:18


30

A volte per popolare un database vuoto da un'origine dati esterna o eseguire il debug di un problema nel database, è necessario disabilitare TUTTI i trigger e i vincoli. per farlo ho utilizzare il seguente codice:

Per disabilitare tutti i vincoli e trigger:

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

Per abilitare tutti i vincoli ei trigger:

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

ho trovato questa soluzione qualche tempo fa su SQLServerCentral, ma necessario per modificare la parte di vincoli di abilitazione come quella originale non ha funzionato completamente


9

Per estendere la risposta di Matt, ecco un esempio fornito su MSDN.

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

4

Un altro approccio è quello di disattivare efficacemente il grilletto senza effettivamente disattivarlo, utilizzando una variabile di stato supplementare incorporato nel grilletto.

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 

Per lo stato di una variabile in grado di leggere un certo tipo di disco di controllo di blocco in una tabella (meglio se limitata al contesto della sessione corrente), utilizzare CONTEXT_INFO(), oppure usa la presenza di una particolare tabella temporanea nome (che è già ambito sessione limitata):

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 

Poi per disabilitare tutti i trigger:

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

Un potenzialmente grave inconveniente è che il grilletto è permanentemente Slowe giù a seconda della complessità di accesso della variabile di stato.

Modifica: aggiunta di un riferimento a questo sorprendentemente simile 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

Non è la migliore risposta per la programmazione dei lotti, ma per gli altri trovare questa domanda in cerca di un modo rapido e semplice per disattivare temporaneamente un trigger, questo può essere realizzato in SQL Server Management Studio.

  1. espandere la cartella trigger sul tavolo
  2. fare clic destro sul grilletto
  3. disabilitare

enter image description here

Seguite la stessa procedura per riattivare.