Методы отладки Oracle
Я не знаю, куда девается информация об ошибке, когда триггер не работает правильно.
Моим инструментом для написания триггеров был инструмент разработчика Sql Oracle, и мои знания о том, как его отлаживать, практически отсутствуют. Каковы некоторые указатели для того, чтобы найти полезную информацию о том, что происходит "за кулисами"? Кроме того, есть ли лучшие инструменты, которые Sql Developer использует для подключения, тестирования, отладки и т. д.?
Мой метод до сих пор состоял в том, чтобы написать что-то (a триггер, например), протестируйте его с помощью одиночных вставок/удалений, а затем надейтесь, что он будет работать от них. Есть ли лучшие способы убедиться, что он делает именно то, что вы хотите? Например, с помощью инструкции select можно ли увидеть (в состоянии отладки или что-то еще) каждый уровень select и как он сокращает результаты? Любые советы очень ценятся.
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.