Як змінити порядок стрільби Тригерів?


12

Дійсно, я рідко використовую тригери. Тож я вперше зіткнувся з проблемою. У мене дуже багато таблиць з тригерами (2 і більше для кожної таблиці). Мені хотілося б знати і змінити порядок стрільби для кожного столу. Чи можливо отримати цю інформацію?

ДОДАТО:

Ось добра знайдена стаття про mssqltips, яку я знайшов.

Відповіді:


12

Ви можете скористатися наступним оператором, щоб перелічити всі тригери в кожній таблиці.

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

Як тільки ви дізнаєтеся всі тригери. Ви можете вручну змінити замовлення за допомогою sp_settriggerorder

alt текст


2
Чи не "після" просто вказує, що тригер визначається як ПІСЛЯ <дія>, а не ВСТАНОВЛЮВАТИ <дія>, а не диктує що-небудь про порядок виконання двох або більше тригерів одного типу?
Девід Спіллетт

@David - так! ви праві
CoderHawk

12

IIRC ви не можете точно гарантувати порядок, який запускає (з однаковим визначенням того, на що реагувати на і коли) вогонь за певну дію проти таблиці, для будь-якої заданої кількості тригерів.

Ви можете хоч, якщо їх три чи менше, так як ви можете використовувати sp_settriggerorder, щоб встановити перший, який буде першим, останній останнім, а той, що знаходиться в середині, мати "невизначений" порядок.

Якщо ваші тригери чутливі до порядку, який виконується в цьому, часто вказує на те, що ваш дизайн стає складнішим, ніж це має бути (як правило, за рахунок органічного росту) і може отримати користь від рефакторингу.


+1 ви маєте рацію, мені доведеться переробити цей код (він складний і має поперечні посилання ...), але я на першому кроці - розслідування.
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
  ;

1
Це виглядає досить гладко. @garik, це працює на ваше оточення? (BTW, початковий коментар SQL також повинен бути частиною кодового блоку.)
Nick Chammas

1
@Nick ти маєш рацію. Я кілька хвилин оглядаю це.
garik

@Nick за замовчуванням ці властивості порожні. тому, якщо виконувати, наприклад, exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'ми можемо побачити результат ("X") у результаті запиту Джексона. Дякую, Джексон.
garik
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.