Я изучаю триггеры, используя Oracle 12 c HR
образец схемы и Oracle Develop PL/SQL Program Units
руководство для студентов. Oracle говорит, что модель выполнения триггера:
- Выполнить все триггеры BEFORE STATEMENT.
- L oop для каждой строки, затронутой оператором SQL:
- Выполнить все триггеры BEFORE ROW для этой строки.
- Выполнить оператор DML И ВЫПОЛНИТЬ ПРОВЕРКУ ОГРАНИЧЕНИЙ ЦЕЛОСТНОСТИ ДЛЯ ЭТОЙ СТРОКИ .
- Выполнить все триггеры AFTER ROW для этой строки row.
- Выполнить все триггеры AFTER STATEMENT.
В примере схемы HR есть таблица EMPLOYEES
с DEPARTMENT_ID
FK, возвращающая DEPARTMENT_ID
PK в DEPARTMENTS
таблица.
Правильно, если я попытаюсь вставить запись в EMPLOYEES
, имеющую значение FK, которого нет среди PK в DEPARTMENTS
, я получу ошибку ORA-02291: integrity constraint (HR.EMP_DEPT_FK) violated - parent key not found
.
В качестве доказательства концепции я создаю следующий триггер BEFORE UPDATE, чтобы вставить отсутствующую запись в DEPARTMENTS
и избежать нарушения ограничения целостности:
CREATE OR REPLACE TRIGGER employee_dept_fk_trg
BEFORE UPDATE OF department_id ON employees
FOR EACH ROW
BEGIN
INSERT INTO departments (department_id, department_name) VALUES(:new.department_id,'Dept '||:new.department_id);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
NULL; -- mask exception if department already exists
END;
Работает нормально ( Я могу вставить несуществующий FK, так как соответствующий PK будет создан f irst).
В учебном материале сказано, что мы могли бы сделать HR.EMP_DEPT_FK
ограничение DEFERRABLE INITIALLY DEFERRED
, чтобы отложить проверку целостности на момент финальной COMMIT
, а не в конце каждого INSERT
(см. Пункт 4 в списке), и поэтому создайте триггер AFTER UPDATE
, а не BEFORE UPDATE
, как в предыдущем.
Есть ли какие-либо преимущества в этом по сравнению с использованием BEFORE UPDATE
trigger?
Перед изменением ограничения HR.EMP_DEPT_FK
, устанавливающего его DEFERRABLE INITIALLY DEFERRED
, я хотел проверить утверждение в пункте 4, поэтому я создал идентичный AFTER UPDATE
триггер и попытался вставить несуществующий FK в таблице сотрудников: Я ПОЛУЧИЛ NO ORA-02291
ERROR, и новая запись PK в таблице DEPARTMENTS
создана! Кажется, что триггер AFTER UPDATE
срабатывает до проверки ограничений целостности, хотя это должно произойти после! (см. пункт 5)
Не могли бы вы мне помочь с этим топи c, пожалуйста?
Всем спасибо, Пино