Информация об исключениях Oracle

#oracle #plsql #oracle11g #oracle10g #ora-06502

#Oracle #plsql #oracle11g #oracle10g #ora-06502

Вопрос:

Мне интересно, есть ли способ получить немного больше информации о том, что вызвало исключение:

 Error starting at line 5 in command:
exec ....
Error report:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at ..., line 558
ORA-06512: at ..., line 752
ORA-06512: at line 1
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    
*Action:
  

Я предполагаю, что это означает, что у меня есть переменная, которая слишком мала для того, что я пытался в нее вставить… Но почему Oracle не может сказать мне, что это за переменная? Было бы здорово, чтобы сотрудники службы отладки и поддержки производства могли сказать нашему клиенту: «Я думаю, что у вас это поле слишком большое, и именно это вызвало ошибку, а не просто «какое-то значение было слишком большим, и мы действительно понятия не имеем, какое именно»… Для использования номера строки потребуется кто-то, кто понимает sql и просматривает код, который не идеален.

Почему в полях Причина и действие ничего нет?

Когда вы пытаетесь вставить в col слишком большие данные, он сообщает вам, какой col… Я хотел бы получить аналогичную информацию здесь.

Возможно ли это без необходимости помещать обработчик исключений после каждой строки кода plsql?

Комментарии:

1. Как бы указание имени локальной переменной PL / SQL дало вам больше информации, чем указание строки кода? Кому-то все равно придется просмотреть код, чтобы определить, что вставляется в эту переменную, чтобы определить корень проблемы и причину. Предполагая, что ваш код использует привязанные типы данных (т. Е. объявляет переменную l_first_name person.first_name%type , а не l_first_name varchar2(100) ), ошибки буфера обычно возникают при объединении данных из нескольких разных столбцов и / или строк, что еще больше усложняет ситуацию.

2. Я должен проанализировать некоторые значения. во время синтаксического анализа я должен сохранять значения в переменной. Они определяются как varcahr2(100) . Допустим, я анализирую коды (просто для упрощения) У меня может быть строка like 'codeA,codeB,codeC' , и у меня есть массив varchar(5) вызываемых объектов CodeArray . Итак, я загружаю коды в массив. Но если я получу похожий код, 'codeAA' я получу исключение, подобное приведенному выше. Если я знаю, что CodeArray переменная вызвала исключение, которое предоставит значение.

3. @kralco626, поэтому специально перехватывайте исключение в этом блоке кода и создавайте собственную ошибку, содержащую информацию, которую вы хотите вернуть.

4. вы предполагаете, что я анализирую только одну строку. Если у меня есть цикл, который анализирует несколько строк или строку, похожую code1#msg1%code2#msg2%code3#msg3 на то, где я пытаюсь разобрать код и сообщение из одной и той же строки, я не буду знать, какое значение вызвало ошибку, только то, что оно было вызвано в этом блоке кода…

Ответ №1:

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

Например, я могу легко сгенерировать вашу ошибку:

 SQL> declare
  2  v_tooshort varchar2(3);
  3  begin
  4    select 'too long' into v_tooshort from dual;
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
  

Ошибка уже указывает номер строки.

Вы бы предпочли, чтобы ошибка указывала имя переменной ( v_tooshort )? Это не полезно для пользователя.

Является ли правильная информация значением «слишком длинным»? Или тот факт, что это фиктивный столбец из dual таблицы? (или фактический столбец и таблица)?

Поскольку ошибка возникает из-за оператора a select into вместо an insert , не похоже, что существует конкретное ограничение базы данных, которое исключение может идентифицировать по имени.

РЕДАКТИРОВАТЬ (для решения проблемы, поднятой в комментарии): это неправда. Вы получите имя и длину столбца, возвращаемые при выполнении an insert (как ORA-12899), но не при выполнении a select into , даже если он использует данные из таблицы:

 SQL> create table test_length (tooshort varchar2(3));

Table created.

SQL> begin
  2    insert into test_length(tooshort) values ('too long');
  3  end;
  4  /
begin
*
ERROR at line 1:
ORA-12899: value too large for column "MYUSER"."TEST_LENGTH"."TOOSHORT"
(actual: 8, maximum: 3)
ORA-06512: at line 2

SQL> insert into test_length(tooshort) values ('abc');

1 row created.

SQL> commit;

Commit complete.

SQL> declare
  2    v_onechar varchar2(1);
  3  begin
  4    select tooshort into v_onechar from test_length;
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
  

ПРАВКА 2:

Вы можете select into вложить свой собственный блок begin-exception-end и вызвать любую понравившуюся ошибку (указав уникальный номер ошибки и описательный текст ошибки):

 SQL> ed
Wrote file afiedt.buf

  1  declare
  2    v_onechar varchar2(1);
  3  begin
  4    select tooshort into v_onechar from test_length;
  5  exception
  6    when value_error then
  7      RAISE_APPLICATION_ERROR(-20011, 'my variable named v_onechar is too short for the data returned from test_lengt
h.tooshort');
  8* end;
SQL> /
declare
*
ERROR at line 1:
ORA-20011: my variable named v_onechar is too short for the data returned from
test_length.tooshort
ORA-06512: at line 7
  

Комментарии:

1. Я понимаю вашу точку зрения, но если бы это был столбец, я бы, по крайней мере, получил информацию expected length 3 got length 8 . Даже эта информация была бы полезна здесь… Если бы это был столбец, я бы также получил имя столбца. Кажется, имеет смысл, что я бы получил то же самое от переменной здесь…

2. Вы можете обработать ошибку с exception помощью предложения в вашем PL / SQL. Мое первое редактирование попыталось показать, как ошибка, которую вы получаете (ORA-06502), сообщает другую информацию, потому что это ошибка, отличная от той, которая предоставляет ожидаемую информацию (ORA-12899).