Выполнение триггеров в определенном порядке
Введение
Проблема, с которой я столкнулся, довольно известна. Я имею два триггера, которые должны отработать в предопределенном порядке, т.е. триггер a должен выполниться сначала, а после него должен отработать триггер b. Вы можете поинтересоваться, а почему бы не иметь один триггер, который объединит триггеры a и b в один триггер ab? Хороший вопрос. К сожалению, триггер a используется для репликации (for replication), в то время как более поздний триггер - не для репликации, что определяет наличие именно двух триггеров.
Давайте создадим испытательную среду. Для этого нам понадобятся две таблицы. Одна - для написания и тестирования триггеров, а вторая - для журнализации триггера и времени его выполнения.
create table [trigger priority] (
[id] [int] identity (1, 1) not null ,
[first] [int] null ,
[second] [int] null ,
[last] [int] null ,
[status] [char] (1) null
) on [primary]
go
Один триггер будет триггером на вставку, который будет обновлять столбец first некоторым случайным числом. Этот триггер будет называться trg_updatefirst
create trigger trg_updatefirst on dbo.[trigger priority]
for insert
as
declare @id int, @val as float
select @id = id from inserted
select @val = floor(rand() * 10)
update [trigger priority] set [first] = @val where id = @id
insert into triggerlog (triggername) values ('trg_updatefirst')
Последняя строка триггера журнализирует имя триггера и время его срабатывания в таблице triggerlog. Следующий триггер используется для обновления столбца second значением из столбца first.
create trigger trg_updatesecond on dbo.[trigger priority]
for insert
as
declare @id int
select @id = id from inserted
update [trigger priority] set [second] = [first] where id = @id
insert into triggerlog (triggername) values ('trg_updatesecond')
Последний триггер используется для обновления столбца last суммой значений столбцов first и second.
create trigger trg_updatelast on dbo.[trigger priority]
for insert
as
declare @id int
select @id = id from inserted
update [trigger priority] set [last] = [first] + [second] where id = @id
insert into triggerlog (triggername) values ('trg_updatelast')
Теперь, чтобы получить ожидаемые результаты, триггеры trg_updatefisrt, trg_updatesecond и trg_updatelast должны выполняться в вышеперечисленном порядке. Что вы об этом думаете? Каков будет порядок? Случайным образом или в некотором особом порядке?
Прежде чем ответить на этот вопрос, давайте посмотрим, что произойдет. После вставки одной записи в таблицу [trigger priority] первый столбец содержит пятерку, что нормально, и второй тоже - 5, что также правильно. Однако в последнем столбце находится null! Почему? Разве не должно быть 10?
Теперь давайте проверим таблицу triggerlog. Порядок столбцов - trg_updatelast, trg_updatefirst и trg_updatesecond. После небольшого исследования выясняется, что триггеры выполняются в том порядке, в котором они были созданы. Таким образом, в идеале триггеры следует создавать в таком порядке: trg_updatefirst, trg_updatesecond и trg_updatelast. Это ни в коем случае не является простой задачей в силу динамического характера процесса разработки, который по большей части не контролируется разработчиками.
Другой вопрос. Как на более поздней стадии Вы собираетесь узнать о порядке срабатывания триггеров?
select * from sysobjects where xtype ='tr' order by id
С помощью вышеупомянутого запроса Вы можете идентифицировать порядок, в котором выполнятся триггеры.
Установить порядок
Теперь вопрос о том, как мы можем задать порядок выполнения. Имеется хранимая системная процедура, которая для того и существует, чтобы ответить на подобный вопрос. Эта хранимая процедура - sp_settriggerorder. У этой sp есть три параметра.
sp_settriggerorder [@triggername =] 'triggername'
, [@order =] 'значение'
, [@stmttype =] 'statement_type'
Первый параметр - это имя триггера, а второй параметр - порядок. Этот порядок может принимать одно из трех значений: " first (первый)", "none (ни первый, ни последний)", и " last (последний)". Последний параметр представляет собой тип триггера, т.е. insert, update или delete. Это означает, что Вы не можете позволить себе иметь четыре или пять триггеров одного и того же типа, которые бы выполнялись в определенном порядке. Однако это вряд ли встречается в практике. По крайней мере, я не встречал еще так много триггеров одного типа на одной таблице.
Этот порядок не может быть установлен опциями alter trigger или create trigger. Если оператор alter trigger изменяет первый или последний триггер, то первоначально установленные на триггере атрибуты first или last удаляются, и значение заменяется на none. Значение порядка должно быть переустановлено с помощью хранимой процедуры sp_settriggerorder.
Разрешения
Владелец триггера и таблицы, на которой определен триггер, имеет разрешение на выполнение sp_settriggerorder. Члены ролей db_owner и db_ddladmin в текущей базе данных, так же как серверная роль sysadmin, могут выполнять эту хранимую процедуру.
Получение порядка
Следующая проблема заключается в установлении порядка, в котором выполняются триггеры, на более поздней стадии. Если я не ошибаюсь, нет никакого прямого способа получить эту информацию из enterprise manager sql server. Вместо этого Вы пишете простые запросы.
select objectproperty(object_id(' trg_updatefirst '), 'execisfirstinserttrigger') execisfirstinserttrigger')
укажет, является ли trg_updatefirst первым (first) триггером на вставку?
Предостережения
Когда Вы генерируете скрипт для триггеров, приоритет их срабатывания не будет заскриптован. Это означает, что Вам придется повторно запустить приоритетные сценарии. Это аргумент в пользу отказа от приоритетных триггеров.
Сервер sql 2005
В sql server 2005 имеется дополнительный параметр в sp_settriggerorder, который должен сообщить, является ли данный триггер триггером базы данных или триггером сервера. Это обусловлено тем, что в sql server 2005 Вы можете написать также ddl триггеры.
Заключение
Установка приоритетного порядка для триггера sql server не составляет труда. Однако Вы должны взять на себя дополнительную заботу, принимая эту возможность в структуре вашей разработки. Будет хорошо, если microsoft может обеспечить решения для рассмотренных выше проблем.
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-04-22 » Комментирование кода и генерация документации в PHP
- 2024-04-22 » SEO в России и на Западе: в чем основные отличия
- 2024-04-22 » SEO для международного масштабирования
- 2024-04-22 » Как использовать XML-карты для продвижения сайта
- 2024-04-22 » Цифровой маркетинг: инструменты для продвижения и рекламы в 2024 году
- 2024-04-22 » Что такое CSS-модули и зачем они нам?
- 2024-04-17 » 23 сервиса для эффективного экспресс-аудита любого сайта
- 2024-04-08 » Яндекс переходит на новую версию Wordstat
- 2024-04-08 » Яндекс интегрировал в свой облачный сервис эмпатичную нейросеть
- 2024-04-08 » Новая версия нейросети Claude превзошла по мощности аналоги Google и OpenAI
- 2024-04-08 » Как пользоваться GPT 4 и Claude бесплатно и без VPN
- 2024-03-13 » Стратегии SEO на 2024 год
- 2024-03-13 » Как использовать анимацию с помощью JavaScript-библиотеки GSAP
- 2024-03-13 » Использование GSAP 3 для веб-анимации
- 2024-03-13 » Cогласование топографической съёмки с эксплуатирующими организациями
- 2024-02-19 » Теряются лиды? Как настроить сквозную аналитику
- 2024-02-17 » Мерч и IT: на что обратить внимание в 2024 году
- 2024-02-16 » Копируем с RSync: основные примеры синхронизации файлов
- 2024-02-15 » Лучшие noCode AI платформы для создания диалоговых ботов
- 2024-02-14 » Факторы ранжирования Google 2024 — исследование Semrush
- 2024-02-12 » Перенос сайта на другой хостинг
- 2024-02-05 » В России сформирован реестр хостинг-провайдеров
- 2024-02-04 » Использование SSH для подключения к удаленному серверу Ubuntu
- 2024-02-03 » Подключаемся к серверу за NAT при помощи туннеля SSH. Простая и понятная инструкция
- 2024-02-02 » Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
- 2024-02-01 » GitLab CI Pipeline. Запуск сценария через SSH на удаленном сервере
- 2024-01-29 » Introduction to GitLab’s CI/CD for Continuous Deployments
- 2024-01-26 » Настройка GitLab CI/CD
- 2024-01-25 » Установка shell gitlab runner
- 2024-01-25 » Установка и регистрация gitlab-runner в docker контейнере
На голодный желудок русский человек ничего делать и думать не хочет, а на сытый - не может Раневская Фаина Георгиевна - (1896-1984) - выдающаяся советская актриса театра и кино |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.