Есть ли способ получить номер строки, в которой было выбрано исключение?
Im работает над pl-sql script, в котором у меня около 10 TO_CHAR-преобразований.
Один из них бросает
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
исключение.
В настоящее время я регистрирую сообщение с помощью этого фрагмента кода
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Exception message is '||SQLERRM(sqlcode));
ROLLBACK;
Я хотел бы добавить (в основном для целей отладки) строку, в которую вызывается исключение, чтобы получить сообщение в форме
ORA-06502: PL/SQL: numeric or value error: character string buffer too small (at line x)
Есть ли простой способ сделать это?
Ответы
Ответ 1
Вам нужно 10g для использования
DBMS_OUTPUT.put_line('Error in '|| $$plsql_unit || ' at ' || $$plsql_line);
также изучите использование
DBMS_UTILITY.format_error_backtrace
есть статья в Oracle Magazine с апреля 2003 года Стивеном Фейерштейном:
http://www.oracle.com/technetwork/issue-archive/2005/05-mar/o25plsql-093886.html
Cheers, niels
Ответ 2
В ответах упомянуты оба, $$PLSQL_LINE & DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
. Но я хотел бы добавить немного о различии между ними:
- Предопределенные директивы запроса
$$PLSQL_LINE & $$PLSQL_UNIT
Предопределенная директива запроса PLSQL_LINE - это литеральное значение PLS_INTEGER, указывающее ссылку на номер строки на $$ PLSQL_LINE в текущем программном блоке.
Из его определения PLSQL_LINE не подходит для ведения журналов исключений, поскольку он будет содержать номер строки исключения, а не номер строки ошибки. Это затрудняет обнаружение местоположения ошибки, особенно с большими программными единицами, если только вы не обертываете каждый оператор обработчиком исключений, как заявил ответ Джеффри.
Однако, хорошая вещь о PLSQL_LINE, она предоставляет номер без необходимости какого-либо извлечения или синтаксического анализа строк. Следовательно, он может быть более подходящим для других целей ведения журнала.
- DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
Эта процедура отображает стек вызовов в точке, где было создано исключение, даже если процедура вызывается из обработчика исключений во внешней области.
Преимущество использования этой процедуры состоит в том, что она предоставляет точный номер строки в программе, где используется ошибка, а не там, где появляется вызов процедуры
Однако процедура возвращает строку типа ORA-XXXXX: at "<program_unit_name>", line xx
. Поэтому, если вы заинтересованы в извлечении самого номера линии, для какой-либо цели ведения журнала вам понадобится разбор строки.
Наконец, чтобы понять разницу, ниже приведены две процедуры с одним и тем же контентом. Вы можете запустить их и заметить разницу выходных данных
CREATE OR REPLACE PROCEDURE proc_plsql_line
IS
BEGIN
RAISE VALUE_ERROR;
EXCEPTION
WHEN VALUE_ERROR
THEN
DBMS_OUTPUT.put_line ( 'Error raised in: '|| $$plsql_unit ||' at line ' || $$plsql_line || ' - '||sqlerrm);
END;
/
и
CREATE OR REPLACE PROCEDURE proc_backtrace
IS
BEGIN
RAISE VALUE_ERROR;
EXCEPTION
WHEN VALUE_ERROR
THEN
DBMS_OUTPUT.put_line ( 'Error raised: '|| DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ' - '||sqlerrm);
END;
/
Исполнение:
exec proc_plsql_line;
Error raised in: PROC_PLSQL_LINE at line 8 - ORA-06502: PL/SQL: numeric or value error
exec proc_backtrace;
Error raised: ORA-06512: at "PROC_BACKTRACE", line 4 - ORA-06502: PL/SQL: numeric or value error
Ответ 3
вам нужно 10 г или выше. Проверьте DBMS_UTILITY.FORMAT_ERROR_BACKTRACE.
http://www.oracle.com/technetwork/issue-archive/2005/05-mar/o25plsql-093886.html
Ответ 4
Вы можете поместить свой обработчик исключений в каждый оператор.
Ответ 5
Оператор DBMS_UTILITY.format_error_backtrace предоставит вам номер строки
begin
select 1/0 from dual;
exception
when others then
dbms_output.put_line('ERROR_STACK: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
dbms_output.put_line('ERROR_BACKTRACE: ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
end;