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

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

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

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

5 ответов


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

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

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

наконец, вы не можете легко увидеть каждый "слой" выберите. План explain обычно расскажет вам, как все идет своим чередом. v$session_longops может указывать, что он делает в настоящее время. Текущее событие ожидания может дать подсказки о том, какая таблица / блок / строка в настоящее время работает.


грубый и готовый простой метод, если вы должны отлаживать триггеры, должен использовать 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

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


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

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

PL / SQL работает на "блоках" кода, и вы можете поймать его с ключевым словом EXCEPTION.

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

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;

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