Методы отладки Oracle - PullRequest
       8

Методы отладки Oracle

8 голосов
/ 17 сентября 2010

Я не знаю, куда отправляется информация об ошибке, когда триггер работает неправильно.

Моим инструментом для написания триггеров был инструмент Oracle Sql Developer, и мои знания о том, как отлаживать его, практически отсутствуют. Каковы некоторые указания для того, чтобы быть в состоянии найти полезную информацию о вещах, происходящих "за кадром"? Кроме того, существуют ли лучшие инструменты Sql Developer для подключения, тестирования, отладки и т. Д.?

Мой метод до сих пор состоял в том, чтобы написать что-то (например, триггер), проверить это с помощью однократных вставок / удалений, а затем надеяться, что это сработает. Есть ли лучшие способы убедиться, что он делает именно то, что вы хотите? Например, с помощью оператора select можно ли в любом случае видеть (в состоянии отладки или что-то еще) каждый уровень выбора и как оно сводит на нет результаты? Любые советы с благодарностью.

Ответы [ 5 ]

14 голосов
/ 17 сентября 2010

Во-первых, весь код работает правильно. Он просто не делает то, что ожидал.

Во-вторых, «Не начинайте отсюда», или, в частности, не используйте триггеры. В основном это будет принудительное переключение на обработку на уровне строк, если триггеры будут срабатывать для каждой строки. Лучше фактически поместить логику в хранимую процедуру, которую вы вызываете. Затем у вас есть начало (где вы проверяете входные данные), а также конец и логический путь на всем пути. Их намного легче отлаживать, если вы идете по одному пути.

Три, Никогда не проверяйте на ошибку, которую вы не знаете, как обработать. Если вы не уловили его, он всплывает к клиенту, который получает сообщение об ошибке, в котором говорится, что пошло не так (сообщение об ошибке) и где (то есть стек ошибок / вызовов) Если вы пытаетесь поймать это, вы должны знать, что с ним делать (и если вы не знаете, тенденция игнорировать это - что ПЛОХО).

Наконец, вы не можете легко увидеть каждый «слой» выбора. План объяснения, как правило, расскажет вам, как идут дела. v $ session_longops МОЖЕТ указывать, что он в данный момент делает. Текущее событие ожидания МОЖЕТ подсказать, над какой таблицей / блоком / строкой оно в данный момент работает.

10 голосов
/ 17 сентября 2010

Простой грубый метод, если вам необходимо отладить триггеры, заключается в использовании DBMS_OUTPUT .

, например

SQL> CREATE OR REPLACE TRIGGER mytrigger
     BEFORE UPDATE ON mytable
     FOR EACH ROW
     ...
     BEGIN
       DBMS_OUTPUT.put_line('mytrigger STARTING');
       ... do some logic ...
       DBMS_OUTPUT.put_line('old=' || :OLD.mycolumn);
       DBMS_OUTPUT.put_line('new=' || :NEW.mycolumn);
       DBMS_OUTPUT.put_line('mytrigger FINISHED');
     END;
     /

SQL> SET SERVEROUT ON
SQL> UPDATE mytable SET mycolumn = mycolumn + 1;
2 rows updated.

mytrigger STARTING
old=10
new=11
mytrigger FINISHED
mytrigger STARTING
old=20
new=21
mytrigger FINISHED
1 голос
/ 20 декабря 2016

В dbForge Studio для Oracle также есть хороший Oracle отладчик , с пошаговым выполнением кода, точками останова, стеком вызовов, наблюдениями, механизмом оценки переменных для хранимых функций Oracle и отладки процедур.автоматизации.

1 голос
/ 17 сентября 2010

SQL Developer имеет хороший отладчик PL / SQL: http://www.packtpub.com/article/debugging-pl-sql-in-oracle-sql-developer

1 голос
/ 17 сентября 2010

Приложение Я использую программу от Quest под названием TOAD, доступную по адресу www.quest.com/toad/toad-for-oracle.aspx.

Как упоминалось выше, DBMS_OUTPUT очень удобен.В вашем редакторе убедитесь, что вы включили окно «Вывод».

PL / SQL работает с «блоками» кода, и вы можете перехватить его с помощью ключевого слова ИСКЛЮЧЕНИЕ.

(Пожалуйста, простите мое форматирование,не уверен, как форматировать для веб)

DECLARE
    C_DATE_FORMAT VARCHAR2(20) := 'DD-Mon-YYYY';
    C_TIME_FORMAT VARCHAR2(20) := 'HH24:MI:SS';
    C_NOT_IMPLEMENTED_CODE CONSTANT NUMBER(5) := -20200;
    C_NOT_IMPLEMENTED_MESSAGE CONSTANT VARCHAR2(255) := 'Not implemented';
    not_implemented EXCEPTION; -- user defined exception
BEGIN
    --RAISE not_implemented; -- raise user defined exception
    RAISE_APPLICATION_ERROR(C_NOT_IMPLEMENTED_CODE, C_NOT_IMPLEMENTED_MESSAGE); -- user defined exception
EXCEPTION -- exception block
    WHEN not_implemented THEN -- catch not_implemented exception
        DBMS_OUTPUT.PUT_LINE('Error: Not implemented');
    WHEN OTHERS THEN -- catch all other exceptions
        DBMS_OUTPUT.PUT_LINE('Error occured.');
        DBMS_OUTPUT.PUT_LINE('Date: ' || TO_CHAR(SYSDATE, C_DATE_FORMAT));
        DBMS_OUTPUT.PUT_LINE('Time: ' || TO_CHAR(SYSDATE, C_TIME_FORMAT));
        DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM); --deal with error
        RAISE; -- raise to calling object
END;
...