Когда запускают огонь, а когда нет - PullRequest
8 голосов
/ 09 августа 2009

Довольно общий вопрос относительно триггеров в SQL Server 2005.

В каких ситуациях запускаются табличные триггеры и в каких ситуациях это не так?

Любые примеры кода для демонстрации были бы великолепны.

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

Пример того, что я имею в виду,

UPDATE MyTable SET name = 'test rows' WHERE id in (1, 2, 3);

Следующая инструкция запускает триггер обновления только один раз.

Ответы [ 4 ]

19 голосов
/ 09 августа 2009

Когда вы хотите, чтобы они стреляли?

CREATE TRIGGER AFTER ACTION

Выполняется после совершения действия (insert update delete). INSTEAD OF срабатывает триггер вместо действия.

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

Кроме того, с триггерами вы будете использовать таблицы inserted и deleted. Обновленные строки перечислены в обоих. Это сбивает с толку многих, потому что они не привыкли думать о update как о delete, а затем insert.

Документация MSDN на самом деле довольно подробно обсуждает, когда срабатывают триггеры и как они влияют здесь .

5 голосов
/ 10 августа 2009

В 2008 году вы можете использовать встроенный Change Data Capture

Также Есть довольно много ситуаций, когда триггеры не срабатывают, например:

· Таблица отброшена.

· Таблица усекается.

· Настройки для вложенных и / или рекурсивных триггеров предотвращают срабатывание триггера.

· Данные загружаются в массе, минуя триггеры.

3 голосов
/ 11 августа 2009

Следующая инструкция запускает триггер обновления только один раз.

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

Если ваш триггер зависит только от одной строки, находящейся одновременно во вставленных или удаленных псевдотаблицах, произойдет сбой. И что еще хуже, он не потерпит неудачу с ошибкой, он просто не повлияет на все строки, которые вы хотите затронуть, независимо от того, что делает триггер. Не исправляйте это с помощью цикла или курсора в триггере, переходите на логику на основе множеств. Курсор в триггере может привести к полной остановке всего приложения, в то время как транзакция из 500 000 записей обрабатывает и блокирует таблицу на несколько часов.

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

2 голосов
/ 09 августа 2009

Я подумал, что выделю ссылку, в которой Эрик опубликовал ситуацию, при которой триггер не сработает:

Хотя оператор TRUNCATE TABLE фактически является DELETE, он не может активировать триггер, поскольку операция не регистрирует отдельные удаления строк. Однако только те, у кого есть права доступа к таблице TRUNCATE TABLE для таблицы, должны быть обеспокоены непреднамеренным обходом триггера DELETE с помощью инструкции TRUNCATE TABLE.

...