Как отследить триггер SQL? - PullRequest
0 голосов
/ 09 июня 2018

Я бы хотел отследить выполнение триггера, но на самом деле я не знаю, как это сделать.С включенной автоматической трассировкой первая мысль, которая пришла мне в голову, - это нажать на курок, но он все еще не работает. Как я могу просмотреть трассировщик выполнения триггера?

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

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 выше.

0 голосов
/ 09 июня 2018

На ум приходят два пути:

Если вы можете изменить код триггера, создайте таблицу журнала и запишите в нее сообщения отладки из тела триггера:

CREATE TABLE trigger_log (t TIMESTAMP, m VARCHAR2(4000));

CREATE OR REPLACE my_trigger BEFORE INSERT ...
BEGIN 
  INSERT INTO trigger_log(t, m)
  VALUES (systimestamp,'my_trigger fired :new_id is='||:new_id);

  ... rest of trigger body ...
END;
/

Во-вторых, еслиВы можете изменить настройки аудита, включить аудит для соответствующей таблицы.

...