
Лабораторные работы БД / Лабораторная 9. Триггеры
.docТриггеры
1. Сравнение триггеров и хранимых процедур
Хранимые процедуры |
Триггеры |
Являются самостоятельным объектом базы данных |
Привязываются к таблице или виду |
Явно вызываются на выполнение командой EXECUTE |
Реагируют на события, связанные с таблицей-владельцем или видом-владельцем |
Могут иметь входные и/или выходные параметры, коды возврата |
Не имеют входных/выходных параметров и кодов возврата |
Могут выполняться в отдельной транзакции |
Выполняются в той же транзакции, в которой осуществляются изменения таблицы-владельца или вида-владельца. |
2. Виды триггеров
Объект |
Действие |
Триггер |
Таблица/вид |
Вставка строк INSERT |
Вместо вставки строк INSTEAD OF |
После вставки строк FOR или AFTER |
||
Модификация строк UPDATE |
Вместо модификации строк INSTEAD OF |
|
После модификации строк FOR или AFTER |
||
Удаление строк DELETE |
Вместо удаления строк INSTEAD OF |
|
После удаления строк FOR или AFTER |
3. Общий синтаксис создания триггера
CREATE TRIGGER <Имя_триггера>
ON <Имя_таблицы_или_вида>
{FOR|AFTER|INSTEAD OF} {[INSERT] [,] [UPDATE] [,] [DELETE]}
AS <SQL-выражения, составляющие тело триггера>
4. Алгоритм обработки триггеров
5. Содержимое таблиц INSERTED и DELETED в зависимости от вида триггера
Вид триггера |
Таблицы INSERTED и DELETED |
INSTEAD OF INSERT |
INSERTED содержит вставляемые в таблицу записи. DELETED пуста. |
FOR INSERT |
INSERTED содержит вставленные в таблицу записи. DELETED пуста. |
INSTEAD OF UPDATE |
INSERTED содержит новые значения модифицируемых записей. DELETED содержит старые значения модифицируемых записей. |
FOR UPDATE |
INSERTED содержит новые значения модифицированных записей. DELETED содержит старые значения модифицированных записей. |
INSTEAD OF DELETE |
INSERTED пуста. DELETED содержит удаляемые записи. |
FOR DELETE |
INSERTED пуста. DELETED содержит удаленные записи. |
Таблицы INSERTED и DELETED – виртуальные, существуют только в период выполнения триггера.
6. Примеры
--6.1. Триггер на поддержание актуального количества товаров при добавлении поставок
CREATE TRIGGER tr_supply_fi
ON supply
FOR INSERT
AS
UPDATE detail
SET detail_quantity = d.detail_quantity + i.supply_quantity
FROM detail d JOIN INSERTED i ON d.detail_id = i.detail_id
--6.2. Триггер на поддержание актуального количества товаров при удалении поставок
CREATE TRIGGER tr_supply_fd
ON supply
AFTER DELETE
AS
UPDATE detail
SET detail_quantity = detail.detail_quantity - DELETED.supply_quantity
FROM detail JOIN DELETED ON detail.detail_id = DELETED.detail_id
--6.3. Триггер на поддержание актуального количества товаров при отпуске деталей в цеха
CREATE TRIGGER tr_delivery_string_fi
ON delivery_string
FOR INSERT
AS
UPDATE detail
SET detail_quantity = d.detail_quantity - i.delivery_quantity
FROM detail d JOIN INSERTED i ON d.detail_id = i.detail_id
--6.3. Проверка допустимости значения даты поставки при добавлении новой поставки
CREATE TRIGGER tr_supply_ii
ON supply
INSTEAD OF INSERT
AS
IF EXISTS (SELECT *
FROM INSERTED
WHERE supply_date > GETDATE())
BEGIN
RAISERROR ('Недопустимое значение даты поставки!', 16, 1)
ROLLBACK TRAN
END
ELSE
INSERT INTO supply (supplier_id, detail_id, supply_date, supply_quantity)
SELECT supplier_id, detail_id, supply_date, supply_quantity
FROM INSERTED
--6.4. Проверка допустимости значения даты поставки при редактировании существующей поставки
CREATE TRIGGER tr_supply_iu
ON supply
INSTEAD OF UPDATE
AS
IF UPDATE (supply_date)
IF EXISTS (SELECT *
FROM INSERTED
WHERE supply_date > GETDATE())
BEGIN
RAISERROR (' Недопустимое значение даты поставки!', 16, 1)
ROLLBACK TRAN
END
ELSE
UPDATE supply
SET supplier_id = i.supplier_id,
detail_id = i.detail_id,
supply_date = i.supply_date,
supply_quantity = i.supply_quantity
FROM supply s JOIN INSERTED i on s.supply_id = i.supply_id