Можно ли узнать, какие триггеры будут срабатывать при запросе?

У меня есть база данных с (тоже) множеством триггеров. Они могут каскадироваться.

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

Есть ли способ узнать, какие триггеры будут запускаться перед запуском запроса или какие триггеры уволили после его запуска (еще не зафиксировано)?

Мне неинтересны запросы, такие как SELECT … FROM user_triggers WHERE …, потому что я их уже знаю, а также потому, что он не говорит мне, будут ли выполняться условия запуска триггеров в моем запросе.

Спасибо

Ответ 1

"У меня есть база данных с (слишком) множеством триггеров. Они могут каскадироваться".

Это только одна из причин, по которым многие люди преследуют триггеры анатамии.

"Есть ли способ узнать, какие триггеры будут срабатывать, прежде чем запускать запрос"

Нет. Давайте рассмотрим что-то, что вы можете найти в теле запуска UPDATE:

if :new.sal > :old.sal * 1.2 then
    insert into big_pay_rises values (:new.empno, :old.sal, :new.sal, sysdate);
end if;

Как мы можем узнать, срабатывает ли триггер BIG_PAY_RISES? Возможно, это может не быть в зависимости от алгоритма, который мы не можем проанализировать из инструкции DML.

Итак, лучшее, на что вы можете надеяться, - это рекурсивный поиск DBA_TRIGGERS и DBA_DEPENDENCIES, чтобы идентифицировать все триггеры, которые могут присутствовать в вашем каскаде. Но будет невозможно определить, какие из них обязательно будут срабатывать в любом конкретном сценарии.

"или какие триггеры запущены после запуска (еще не зафиксированы)?

Как указывали другие, регистрация является одним из вариантов. Но если вы используете Oracle 11g, у вас есть еще один вариант: Иерархический профилировщик PL/SQL. Это неинтрузивный инструмент, который отслеживает все программные модули PL/SQL, затронутые вызовом PL/SQL, включая триггеры. Одной из интересных особенностей Иерархического профилировщика является то, что он включает в себя PU, которые принадлежат другим схемам, которые могут быть полезны для каскадных триггеров.

Итак, вам просто нужно обернуть свой SQL в анонимный блок и вызвать его с помощью иерархического профилировщика. Затем вы можете отфильтровать отчет, чтобы показывать только триггеры, которые запускались. Узнайте больше.

Ответ 2

Есть ли способ узнать, какие триггеры будут запускаться перед запуском запроса, или какие триггеры уволили после его запуска (еще не зафиксировано)?

Чтобы решить эту проблему, я бы выполнил запрос внутри анонимного блока, используя отладчик PL/SQL.

Ответ 3

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

select  trigger_name
,   trigger_type
,   status
from    dba_triggers
where   owner = '&owner'
and table_name = '&table'
order by status, trigger_name