SQL Server 2005: T-SQL do tymczasowego wyłączenia wyzwalacza


44

Czy można wyłączyć wyzwalacz dla partii poleceń, a następnie włączyć go, gdy partia jest skończona?

Jestem pewien, że mógłbym rzucić spust i ponownie go dodać, ale zastanawiałem się, czy istnieje inny sposób.

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

następnie odwrotność:

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

Dzięki! Myślę, że moja naiwność SQL Server 2005 jest zbyt dobra na tej stronie. 23 wrz. 082008-09-23 20:15:46

  0

Bez obaw; być DBA przez długi czas i te rzeczy stają się automatyczne :) 23 wrz. 082008-09-23 20:16:41

  0

tj. jeśli używasz opcji modyfikacji wyzwalacza, a skrypt zawiera 'ALTER TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWszystko]' then you need 'WYŁĄCZ TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWszystko] 'i' ENABLE TRIGGER [dbo]. [trgWhatever] ON [dbo]. [tblWszystko] ' 22 wrz. 152015-09-22 14:45:41

  0

UWAGA - Otrzymuję komunikat o błędzie" Niepoprawna składnia w pobliżu "DISABLE". " chyba że umieściłem ';' pomiędzy "PRINT" Some message "; WYŁĄCZ WYZWALANIE [dbo] ..... ' 23 wrz. 152015-09-23 15:22:06


15

Jednakże, jest prawie zawsze zły pomysł, aby to zrobić. Będziesz bałagan w integralności bazy danych. Nie rób tego bez uwzględnienia konsekwencji i sprawdzania za pomocą dbas, jeśli je posiadasz.

Jeśli postępujesz zgodnie z kodem Matta, pamiętaj o ponownym włączeniu spustu. I pamiętaj, że wyzwalacz jest wyłączony dla wszystkich, którzy wstawiają, aktualizują lub usuwają z tabeli, gdy jest ona wyłączona, nie tylko dla twojego procesu, więc jeśli to musi być zrobione, to rób to w godzinach, kiedy baza danych jest najmniej aktywna (i najlepiej w trybie pojedynczego użytkownika).

Aby wykonać import dużej ilości danych, należy wziąć pod uwagę, że wkładka zbiorcza nie uruchamia wyzwalaczy. Ale wtedy proces po wstawieniu zbiorczym będzie musiał naprawić wszystkie problemy z integralnością danych wprowadzone przez użytkownika lub wyzwalanie wyzwalaczy.

  0

Świetne punkty. Powodem, dla którego tego potrzebowałem, było kopiowanie danych ze środowiska produkcyjnego do środowiska testowego, w którym niektóre AKy były resetowane przez wyzwalacz, ale powiązane kolumny w innej tabeli nie nadążały za tym. 23 wrz. 082008-09-23 21:12:18


30

Czasami, aby wypełnić pustą bazę danych z zewnętrznego źródła danych lub debugować problem w bazie danych, należy wyłączyć WSZYSTKIE wyzwalacze i ograniczenia. celu należy użyć następującego kodu:

aby wyłączyć wszystkie ograniczenia i wyzwala:

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

Aby włączyć wszystkie ograniczenia i wyzwala:

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

Znalazłem takie rozwiązanie jakiś czas temu na SQLServerCentral, ale konieczne było zmodyfikowanie części z włączonymi ograniczeniami, ponieważ oryginalna nie działała w pełni


9

Aby przedłużyć odpowiedź Matta, oto przykład podany na MSDN.

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

4

Innym podejściem jest skutecznie wyłączyć spust bez faktycznego wyłączenia go, wykorzystując dodatkową zmienną stanu, która jest uwzględniona w spuście.

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 

Dla państwa zmienna można było przeczytać jakiś rodzaj blokady rekordu sterowania w tabeli (najlepiej, jeśli ogranicza się do kontekście bieżącej sesji), użyj CONTEXT_INFO(), lub skorzystać z obecności konkretnej tabeli temp nazwa (która jest już ograniczony zakres sesji):

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 

Następnie wyłączyć wszystkie wyzwalacze:

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

potencjalnie poważnym minusem jest to, że wyzwalacz jest trwale slowe d w zależności od złożoności dostępu do zmiennej stanu.

Edytuj: Dodawanie odniesienia do tego niezwykle podobnego 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

Nie jest to najlepsze rozwiązanie dla programowania wsadowego, ale dla innych znalezienie na to pytanie w poszukiwaniu szybki i łatwy sposób, aby tymczasowo wyłączyć spust, można to osiągnąć w SQL Server Management Studio.

  1. rozwinąć folder wyzwalaczy na stole
  2. prawym przyciskiem spust
  3. wyłączyć

enter image description here

Wykonaj tę samą procedurę, aby ponownie włączyć.