Oracle дает вам два хороших способа трассировки PL / SQL.Предпочтительным способом является использование пакета DBMS_HPROF.Менее хорошим (он старше) является DBMS_PROFILER.
Поскольку DBMS_PROFILER проще и ваши требования просты, я продемонстрирую это.
Сначала давайте создадим таблицу с триггером:
CREATE TABLE matt_test1 ( a number );
CREATE TRIGGER matt_trg1 BEFORE INSERT ON matt_test1 FOR EACH ROW
BEGIN
NULL;
END;
Далее мы запускаем профилировщик, запускаем INSERT
(который должен запустить наш триггер) и затем останавливаем профилировщик:
EXEC DBMS_PROFILER.START_PROFILER;
INSERT INTO matt_test1 (a) values (1);
EXEC DBMS_PROFILER.STOP_PROFILER;
Теперь есть лучшие способызапустить и остановить профилировщик.Эти способы вернут идентификатор запуска, который был использован, который вам понадобится для запроса результатов.В нашем быстром и грязном примере мы просто рассмотрим самые последние результаты профилировщика:
SELECT * FROM plsql_profiler_runs order by runid desc;
В моей системе это было runid
2.
След.мы запрашиваем таблицы PLSQL_PROFILER*
, чтобы получить всю информацию о PL / SQL, которая была выполнена во время выполнения.Это не просто список триггеров - это будет намного больше: практически любой оператор SQL, вызываемый из PL / SQL, и почти любой другой блок PL / SQL (процедура или функция), вызываемый из PL / SQL.
Вот запрос, который я использовал для этого (прежде чем я переключился на использование DBMS_HPROF
для этого:
SELECT d.runid,
u.unit_type,
u.unit_owner,
u.unit_name,
d.line#,
d.total_occur,
d.total_time / POWER (10, 9) total_seconds,
d.min_time / POWER (10, 9) min_seconds,
d.max_time / POWER (10, 9) max_seconds,
ss.source line_text,
SUM (d.total_time / POWER (10, 9)) OVER (PARTITION BY NULL ORDER BY d.total_time DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
cumulative_seconds,
SUM (d.total_time / POWER (10, 9)) OVER (PARTITION BY NULL) elapsed_seconds_for_run
FROM plsql_profiler_data d INNER JOIN plsql_profiler_units u ON u.runid = d.runid
AND u.unit_number = d.unit_number
LEFT JOIN SYS.user$ su ON su.NAME = u.unit_owner
LEFT JOIN SYS.obj$ so
ON so.NAME = u.unit_name
AND so.owner# = su.user#
AND DECODE (so.type#,
7, 'PROCEDURE',
8, 'FUNCTION',
9, 'PACKAGE',
11, 'PACKAGE BODY',
12, 'TRIGGER',
13, 'TYPE',
14, 'TYPE BODY',
'UNDEFINED') = u.unit_type
LEFT JOIN SYS.source$ ss ON ss.obj# = so.obj#
AND ss.line = d.line#
WHERE 1=1
and d.runid = 2
AND d.total_occur > 0
ORDER BY d.total_time DESC;
Наконец, результаты:
+-------+-----------------+-------------+-------------+-------+-------------+---------------+-------------+-------------+-----------+--------------------+-------------------------+
| RUNID | UNIT_TYPE | UNIT_OWNER | UNIT_NAME | LINE# | TOTAL_OCCUR | TOTAL_SECONDS | MIN_SECONDS | MAX_SECONDS | LINE_TEXT | CUMULATIVE_SECONDS | ELAPSED_SECONDS_FOR_RUN |
+-------+-----------------+-------------+-------------+-------+-------------+---------------+-------------+-------------+-----------+--------------------+-------------------------+
| 2 | ANONYMOUS BLOCK | <anonymous> | <anonymous> | 1 | 2 | 0.000010001 | 0.000001 | 0.000008001 | | 0.000010001 | 0.000013001 |
| 2 | TRIGGER | APPS | MATT_TRG1 | 2 | 1 | 0.000002 | 0.000002 | 0.000002 | BEGIN | 0.000012001 | 0.000013001 |
| 2 | ANONYMOUS BLOCK | <anonymous> | <anonymous> | 1 | 1 | 0.000001 | 0.000001 | 0.000001 | | 0.000013001 | 0.000013001 |
+-------+-----------------+-------------+-------------+-------+-------------+---------------+-------------+-------------+-----------+--------------------+-------------------------+
Вы можетеПосмотрите, как наш триггер срабатывает в строке №2 выше.