Подтвердить что ты не робот

Есть ли способ получить номер строки, в которой было выбрано исключение?

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)

Есть ли простой способ сделать это?

4b9b3361

Ответ 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

Ответ 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;