Jak zmienić kolejność wyzwalania wyzwalaczy?

12

Naprawdę rzadko używam wyzwalaczy. Więc spotkałem problem za pierwszym razem. Mam dużo tabel z wyzwalaczami (2 lub więcej na każdy stół). Chciałbym poznać i zmienić kolejność wyzwalania wyzwalaczy dla każdego stołu. Czy można uzyskać te informacje?

DODANY:

Oto dobry artykuł na temat mssqltips , które znalazłem.

garik
źródło

Odpowiedzi:

12

Możesz użyć poniższej instrukcji, aby wyświetlić listę wszystkich wyzwalaczy w każdej tabeli.

EXEC sp_MSForEachTable 'PRINT ''?'' 
EXEC sp_helptrigger ''?'''

Gdy znajdziesz wszystkie wyzwalacze. Możesz ręcznie zmienić kolejność za pomocą sp_settriggerorder

alternatywny tekst

CoderHawk
źródło
2
Czy „isafter” po prostu nie wskazuje, że wyzwalacz jest zdefiniowany jako PO <działaniu>, a NIE ZAMIAST <działania>, a nie dyktuje cokolwiek na temat kolejności wykonania dwóch lub więcej wyzwalaczy tego samego typu?
David Spillett,
@David - tak! masz rację
CoderHawk
12

IIRC nie można dokładnie zagwarantować kolejności, która wyzwala (z taką samą definicją, na co i kiedy zareagować) wystrzelić dla danej akcji przeciwko stole, dla dowolnej liczby wyzwalaczy.

Możesz jednak, jeśli są trzy lub mniej, ponieważ możesz użyć sp_settriggerorder, aby ustawić pierwszy na pierwszy, ostatni na ostatni, a środkowy na „niezdefiniowany” porządek.

Jeśli Twoje wyzwalacze są wrażliwe na kolejność, która jest wykonywana w ten sposób, często oznacza to, że twój projekt staje się bardziej złożony niż to konieczne (zwykle z powodu wzrostu organicznego) i może skorzystać z pewnego refaktoryzacji.

David Spillett
źródło
+1 masz rację, muszę zmienić kod tego kodu (jest skomplikowany i ma linki krzyżowe ...), ale jestem na pierwszym etapie - dochodzenie.
garik
5
-- List tables with triggers and their firing order.  By Jackson Jarvis.
SELECT [tbl].[name] AS 'Table'
      ,[trg].[name] AS 'Trigger'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete Last'
  FROM            [sysobjects] AS [trg] WITH (NOLOCK)
       INNER JOIN [sysobjects] AS [tbl] WITH (NOLOCK)
            ON  [trg].[parent_obj] = [tbl].[id]
  WHERE [trg].[TYPE] IN (N'TR')
  ORDER BY
       [tbl].[name] ASC
      ,[trg].[name] ASC
  ;
Jackson Jarvis
źródło
1
To wygląda całkiem gładko. @garik, czy to działa w twoim środowisku? (BTW, początkowy komentarz SQL powinien być również częścią bloku kodu.)
Nick Chammas
1
@Nick masz rację. Rozglądam się przez kilka minut.
garik
@ Domyślnie te właściwości są puste. więc jeśli wykonasz, na przykład exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'możemy zobaczyć wynik („X”) w wyniku zapytania Jacksona. Dzięki, Jackson.
garik