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


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

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

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

5 6

5 ответов:

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

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

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

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

Грубый и готовый простой метод, если вы должны отлаживать триггеры, должен использовать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 есть хороший отладчик PL / SQL: http://www.packtpub.com/article/debugging-pl-sql-in-oracle-sql-developer

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

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

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

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

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;

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