2008-09-18 3 views
25

Кто-нибудь знает, как SQL Server определяет триггеры ордеров (того же типа, т. Е. Перед триггерами). И есть ли способ изменить это, чтобы я мог указать порядок, который я хочу. Если нет, почему бы и нет.Триггеры SQL Server - порядок выполнения

Спасибо.

ответ

2

Заказ устанавливается сервером sql, единственное, что вы можете сделать, это использовать систему sp (sp_settriggerorder), чтобы установить, какой триггер будет запускаться первым и который будет гореть последним.

Помимо установки первого и последнего триггеров, вы не можете изменить или указать, какой сервер SQL будет использоваться. Поэтому вы захотите построить свои триггеры, чтобы они не полагались на то, какой заказ уволен. Даже если вы определите порядок, который они запускают сегодня, это может измениться завтра.

Эта информация основана на Sql Server 2000, однако я не верю, что 2005/2008 действует по-разному в этом отношении.

4

Используйте хранимую процедуру sp_Settriggerorder, вы можете определить порядок выполнения триггера.

sp_settriggerorder [ @triggername = ] ‘[ triggerschema. ] triggername’ 
, [ @order = ] ‘value’ 
, [ @stmttype = ] ’statement_type’ 
[ , [ @namespace = ] { ‘DATABASE’ | ‘SERVER’ | NULL } ] 

Второй параметр, «порядок» может принимать три значения, что означает, что он может принимать во внимание вверх трех триггеров.

  1. Первый - триггер срабатывает первый
  2. Последняя - Триггер не обжигают последний
  3. None - Триггер срабатывает в случайном порядке.
1

Используйте эту систему хранимая процедура:

sp_settriggerorder[@triggername = ] 'triggername', [@order = ] 'value', [@stmttype = ] 'statement_type' 
5

sp_settriggerorder относится только к ПОСЛЕ триггеров.

4

Вы можете гарантировать, что срабатывает триггер, который запускается последним, а какие - в середине, используя sp_settriggerorder. Если вам нужно синхронизировать более трех, это не представляется возможным в SQL Server 2005.

Вот пример, взятый из here (Связанная статья содержит гораздо больше информации).

sp_settriggerorder [ @triggername = ] ‘[ triggerschema. ] triggername’ 
, [ @order = ] ‘value’ 
, [ @stmttype = ] ’statement_type’ 
[ , [ @namespace = ] { ‘DATABASE’ | ‘SERVER’ | NULL } ] 
10

Если ваш в точке беспокоиться о триггерных заказах, то вы действительно должны сделать шаг назад и рассмотреть то, что вы пытаетесь сделать, и если есть лучший способ сделать это. Тот факт, что это нелегко изменить, должно сказать вам кое-что.

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

17

Использование SetTriggerOrder это хорошо, но если ваш код зависит от конкретной последовательности выполнения, почему бы не завернуть все триггера в хранимые процедуры, и есть первый один вызов вторых, вторые вызывают третьи и т.д.

Затем вы просто выполняете первый запуск в триггере.

Кто-то в будущем будет благодарен, что им не нужно было копаться в системной таблице, чтобы определить пользовательскую последовательность выполнения.

+7

Как правило, мы этого не делаем, потому что у нас нет простого доступа к вложенным и удаленным псевдоматериалам в хранимых процедурах. – mwigdahl 2012-06-27 13:57:52

14

Вы можете использовать sp_settriggerorder, чтобы определить порядок каждого триггера на столе.

Однако я бы сказал, что вам будет намного лучше иметь один триггер, который выполняет несколько действий. Это особенно, поэтому, если заказ важен, поскольку это значение не будет очень очевидным, если у вас есть несколько триггеров. Представьте, что кто-то пытается поддерживать базу данных месяцев/лет вниз по дорожке. Конечно, вероятно, будут случаи, когда вам нужно иметь несколько триггеров или это действительно лучший дизайн, но я бы начал предполагать, что у вас должен быть один и работать оттуда.

1

миллион долларов заявление в связи с этим -

sp_settriggerorder: Определяет ПОСЛЕ триггеры, срабатывающие первым или последним. Триггеры AFTER, запущенные между первым и последним триггерами, выполняются в неопределенном порядке.

Источник: MSDN

2

Использование Это:

Например:

USE AdventureWorks; 
GO 
EXEC sys.sp_settriggerorder @triggername = N'', -- nvarchar(517) 
    @order = '', -- varchar(10) 
    @stmttype = '', -- varchar(50) 
    @namespace = '' -- varchar(10) 

Первый и последний триггеры должны быть двумя различными триггерами.

Первый: триггер уволен первым.

Последнее: триггер уволен последним.

Нет: триггер запускается в неопределенном порядке.

И эта ссылка для стоимости @stmttype: DDL Events

И для @namespace = { 'DATABASE' | «СЕРВЕР» | NULL} и для получения дополнительной информации см .: DDL Triggers