#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).