Не ко всем таблицам и столбцам можно обращаться из тела триггера. В этом контексте необходимо различать изменяющиеся и ограничивающие таблицы. Изменяющаяся таблиц a (mutating table) - это таблица, которая в данный момент модифицируется оператором DML. Для триггера это таблица, для которой он был создан. Таблицы, которые обновляются в результате реализации ограничений ссылочной целостности DELETE CASCADE (каскадное удаление), также являются изменяющимися (см. "Oracle Server Reference"). Ограничивающая таблица (constraining table) — это таблица, информация которой может быть считана при реализации ограничения ссылочной целостности. Поясним это определение на примере таблицы registered students:
Для таблицы registered_students установлены два ограничения ссылочной целостности. Таблицы students и classes являются ограничивающими по отношению к registered_students. Их информацию, возможно, потребуется модифицировать и/или считать оператором DML. Таблица registeredstudents тоже изменяется во время выполнения над ней оператора DML.
SQL-операторы в теле триггера не могут:
Считывать или модифицировать информацию таблицы, изменяющейся в результате выполнения активизирующего оператора. В число таких таблиц входит и сама активизирующая таблица.
Считывать или модифицировать информацию столбца первичного ключа, уникальных столбцов и столбцов внешних ключей таблицы, являющейся ограничивающей по отношению к активизирующей таблице. Другие столбцы модифицировать можно.
Эти правила справедливы для всех строковых триггеров. Для операторных триггеров они применимы только в тех случаях, когда те активизируются в результате выполнения операции каскадного удаления информации (DELETE CASCADE).
Внимание
Если оператор INSERT воздействует только на одну строку, то для строковых триггеров BEFORE и AFTER, работающих с данной строкой, активизирующая таблица не является изменяющейся. Это единственная ситуация, когда строковый триггер может считывать и модифицировать информацию активизирующей таблицы. Для таких операторов, как INSERT INTO table SELECT .... активизирующая таблица всегда является изменяющейся, даже если в подзапросе возвращается только одна строка.
В качестве примера рассмотрим триггер. Он модифицирует таблицы students и classes, тем не менее допустим, так как модифицируемые столбцы таблиц students и classes не являются ключевыми столбцами. Пример недопустимого триггера будет рассмотрен в следующем разделе.
WHERE ID = :new.student_id;
-- Добавим единицу к числу студентов в группе.
UPDATE classes
SET current_students = current_students + 1 'WHERE department = : new. department AND course = :new.course; END CascadeRSInserts;
Пример изменяющейся таблицы
Предположим, что требуется ограничить общее число студентов, занимающихся каждой из дисциплин, пятью учащимися. Это можно сделать, если создать для таблицы students строковый триггер BEFORE INSERT или UPDATE:
Ошибка ORA-4091 возникает в результате того, что триггер LimitMajors обращается к собственной активизирующей таблице, которая изменяется. ORA-4091 устанавливается при активизации, а не при создании триггера.
< Предыдущая | Следующая > |
---|