Вопрос. У меня есть таблица и два или больше триггеров AFTER INSERT/AFTER DELETE. У меня есть два-три триггера AFTER INSERT для одной и той же таблицы. Можете ли вы рассказать о порядке срабатывания триггеров AFTER INSERT? (Я пытался определить это, используя отметки времени (time stamps), но все они указывают одинаковое время).
Ответ. О порядке срабатывания триггеров я могу сказать только следующее:
В пределах одного типа триггеров вы не должны рассчитывать на порядок срабатывания этих триггеров. Даже если вы обнаружили, что три триггера BEFORE запускаются в таком порядке: TRIGGER_A, TRIGGER_B, TRIGGER_C; вы не можете полагаться на это. В документации Oracle (Сервер Oracle Database. Руководство разработчика приложений. Основы) ясно написано: "Если для таблицы существует несколько триггеров одного типа, СУБД Oracle выполняет их в произвольном порядке".
Если ваши триггеры зависят от порядка срабатывания, вы должны объединить их в один триггер. На самом деле я рекомендую, чтобы во всех триггерах вызывались хранимые процедуры, так что большинство ваших триггеров будут состоять из одной строки – вызова процедуры. Таким образом вы сможете взять два-три триггера AFTER INSERT, разместить их код в хороших модульных процедурах пакета, а затем вызывать их в правильном порядке в одном триггере.
Побочное примечание: во время интерактивного обсуждения возник вопрос: "Почему в СУБД Oracle вообще разрешается использование множественных триггеров одного и того же типа"? Причина восходит к первоначальной реализации в сервере Oracle Database механизма тиражирования. В журналах материализованных представлений (materialized view logs) – раньше в версии 7.0 они назывались просто журналами моментальных копий (snapshot logs) – для регистрации операций языка манипулирования данными (DML), которые выполнялись на данной таблице, использовались триггеры базы данных. До поддержки в сервере базы данных множественных триггеров одного и того же типа это накладывало на разработчиков ограничение: либо не использовать сам этот тип триггеров (который уже использовался сервером Oracle), либо не использовать журналы материализованных представлений. Ни один из тех вариантов не был привлекательным, поэтому в сервер базы данных была добавлена возможность использования множественных триггеров одного и того же типа.
Важно, чтобы при использовании множественных триггеров одного и того же типа вы гарантировали, что между ним нет никакой зависимости – особенно относительно порядка их срабатывания, поскольку вы никогда не сможете им управлять.