sp_configure ‘nested triggers’, 0
Вы можете захотеть отключить вложенность триггеров потому что:
Вложенные триггеры требует комплексный и хорошо планированный дизайн. Каскадное изменение может изменить данные, на которые вы не хотели воздействовать.
Изменение данных в любой точке последовательности вложенных триггеров отключает серию триггеров.
Любой триггер может содержать операторы UPDATE, INSERT или DELETE, которые воздействуют на другие таблицы или ту же самую таблицу. Если включена опция рекурсивного вызова, триггер, который изменяет данные в таблице, может активировать себя снова. По умолчанию эта опция отключена, когда база данных создаётся. Вы можете включить эту опцию с помощью оператора ALTER DATABASE.
Следующий оператор включает рекурсивные триггеры:
ALTER DATABASE ClassNorthwind SET RECURSIVE_TRIGGERS ON
sp_dboption имябазыданных, ‘recursive triggers’, TRUE
Если опция вложения отключена, то и рекурсия тоже отключена.
Триггеры гарантируют целостность данных и бизнес правила. Вы можете возложить некоторые действия, которые выполняет триггеры на ограничения. Первым делом вы должны рассматривать ограничения. Однако, роли позволяют обеспечить более сложные бизнес правила.
Вы можете использовать триггеры для обеспечения целостности данных с помощью каскадных изменений в связанных таблицах в базах данных.
Пример
Следующий пример показывает, как триггер обеспечивает целостность данных в таблице BackOrders. Триггер содержит список продуктов в таблице BackOrders. Когда продукт получен, триггер обновления для таблицы Products удаляет строки из таблицы BackOrders.
USE Northwind
GO
CREATE TRIGGER BackOrderList_Delete
ON Products FOR UPDATE
AS
IF (SELECT BO.ProductID FROM BackOrders AS BO JOIN
Inserted AS I ON BO.ProductID=I.ProductID)>0
BEGIN
DELETE BO FROM BackOrders AS BO
INNER JOIN Inserted AS I
ON BO.ProductID=I.ProductID
END
Вы можете использовать триггеры для обеспечения бизнес правил, которые более сложны, чем ограничение CHECK.
Для примера, вы можете захотеть убедится, что пользователи оплатили, прежде чем их позволят отключить от членства.
Пример
Следующий пример показывает, как триггер определяет, какие продукты имеют историю закупок. Если она существует, то происходит откат удаления и триггер возвращает сообщение об ошибке:
USE Northwind
GO
CREATE TRIGGER Product_Delete
ON Products FOR DELETE
AS
IF (SELECT COUNT (*)
FROM [Order Details] INNER JOIN deleted
ON [Order Details].ProductID=Deleted.ProductID
)>0
BEGIN
RAISERROR('Транзакция не может быть принята, этот продукт имеет историю', 16,1)
ROLLBACK TRANSACTION
END
Вы должны принять к сведению следующие замечания, когда используете триггеры:
Триггеры выполняются быстро, потому что таблицы Insert и Deleted расположены в КЭШе.
Количество ссылочных таблиц и количество строк влияют на время выполнения.
Действия, содержащиеся в триггере, являются частью транзакции.
Используйте триггеры только там, где это необходимо. Используйте ограничения, прежде чем использовать триггеры;
Делайте объявление операторов триггеров простыми, на сколько это возможно. Так как триггер является частью транзакции, блокировки сохраняются, пока транзакция не завершится;
Включайте проверку рекурсии в рекурсивных триггерах;
Минимизируйте использование операторов ROLLBACK в триггерах.
Рассмотрите следующее создание триггера:
USE ClassNorthwind
IF EXISTS ( SELECT name FROM sysobjects
WHERE type = 'TR' AND name = 'OrdDet_Insert' )
DROP TRIGGER OrdDet_Insert
GO
CREATE TRIGGER OrdDet_Insert
ON [Order Details]
FOR INSERT
AS
UPDATE P SET
UnitsInStock = (P.UnitsInStock - I.Quantity)
FROM Products AS P INNER JOIN Inserted AS I
ON P.ProductID = I.ProductID
GO
/* Display results. */
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.