Галерея
7757 8119 8300 8698 8817 9504 9722 9937
Интересные записи
Топовые новости
Новое

Инструкция CREATE/ALTER TRIGGER общие правила

По умолчанию триггеры запускаются один раз на уровне инструкции. То есть одна инструкция INSERT может вставить в таблицу 500 строк, но триггер вставки в этой таблице выполнится только один раз. Некоторые производители позволяют запускать триггер для каждой операции по модификации данных. В этом случае инструкция, вставляющая 500 строк в таблицу, запустит триггер уровня строки 500 раз, по одному разу для каждой строки.

Помимо привязки к конкретной инструкции по модификации данной таблицы (INSERT, UPDATE или DELETE) триггеры имеют конкретное время запуска. В общем случае триггеры могут запускаться до (BEFORE) обработки инструкции по модификации, после (AFTER) ее обработки или (если это поддерживается разработчиком) вместо обработки инструкции (INSTEAD OF). Триггеры, которые запускаются до или вместо инструкции по модификации, не видят изменений, производимых инструкцией, тогда как те триггеры, которые запускаются после модификации, могут видеть эти изменения и воздействовать на них.

Триггеры используют две псевдотаблицы. Эти псевдотаблицы являются таковыми в том смысле, что они не объявляются при помощи инструкций CREATE TABLE, но логически существуют в базе данных. Эти псевдотаблицы на разных платформах имеют разные имена, но мы будем здесь называть их Before и After. Их структура в точности повторяет структуру таблицы, с которой связан триггер. Таблица Before содержит моментальный снимок всех строк таблицы до запуска триггера, а таблица After — снимок всех записей после события, запустившего триггер. С помощью операторов сравнения вы можете сравнивать данные до и после запуска триггера, определяя, что точно нужно сделать.

Ниже приводится триггер BEFORE платформы Oracle, который использует для сравнения значений псевдотаблицы OLD и NEW. (Для сравнения: SQL Server таким же образом использует псевдотаблицы DELETED и INSERTED, a DB2 ТРЕБУЕТ, чтобы вы в предложении REFERENCING присвоили имена псевдотаблицам.) Этот триггер создает запись аудита перед изменением записи о зарплате служащего.

CREATE TRIGGER if_emp_changes BEFORE DELETE OR
UPDATE ON employee FOR EACH ROW WHEN (new.emp_salary old.emp_salary)
BEGIN
INSERT INTO employee_audit
VALUES (‘old’, :old.emp_id, ;old.emp_salary, :old.emp_ssn); END;

Вы также можете пользоваться возможностями, которые дает каждая платформа, чтобы сделать триггеры более функциональными и упростить программирование. Например, в Oracle есть специальное предложение IF … THEN, которое используется только в триггерах. Это предложение имеет следующие формы: IF DELETING THEN, IF INSERTING THEN или IF UPDATING THEN. В следующем примере в системе Oracle создается триггер удаления и обновления, в котором используется предложение IF DELETING THEN.

CREATE TRIGGER if_emp_changes BEFORE DELETE OR
UPDATE ON employee FOR EACH ROW
BEGIN
IF DELETING THEN
INSERT INTO employee_audit
VALUES (‘DELETED’, :old.emp_id, :old.emp_salary, :old.emp_ssn);
ELSE
INSERT INTO employee_audit
VALUES (‘UPDATED’, :old.emp_id, :new.emp_salary, :old.emp_ssn);
END IF;
END;

В примере для SQL Server в базу данных добавлена новая таблица contractor. Все записи в таблице employee, которые показывают, что служащий работает по контракту, перенесены в таблицу contractor. Теперь все новые служащие, вносимые в таблицу employee, попадают вместо этого в таблицу contractor при помощи триггера INSTEAD OF INSERT.

CREATE TRIGGER if_emp_is_contractor —
INSTEAD OF INSERT ON employee
BEGIN
INSERT INTO contractor
SELECT * FROM inserted WHERE status=’CON’ INSERT INTO employee
SELECT * FROM inserted WHERE status=’FTE’
END GO

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

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

Источник