ОРА-06502 с ОРА-06512

У меня есть процедура, в которой я пытаюсь написать исходный код (1290 строк) в dbms_output следующим образом:

dbms_output.put_line(DBMS_METADATA.GET_DDL('FUNCTION', 'name', 'owner')); --MYPROC, line 6

Я получаю :

ORA-06502: PL/SQL: numeric or value error
ORA-06512: in "MYPROC", line 6

. Эта ошибка возникает в toad. Я могу выполнить на вкладке редактора жабы:

SELECT DBMS_METADATA.GET_DDL('FUNCTION', 'name', 'owner') FROM DUAL;

Я имею в виду, что получаю исходный код в «Сетке данных».

То же самое происходит, когда я пытаюсь сохранить код в переменной CLOB:

src CLOB;
...
src := DBMS_METADATA.GET_DDL('FUNCTION', 'name', 'owner') ; --MYPROC, line 6

Любая подсказка?

Вы сказали, что функция составляет 1290 строк, но сколько в ней символов - если она больше 32 КБ, вам нужно разбить ее на более мелкие фрагменты. Вот так может быть.

Alex Poole 15.02.2023 13:51

Вам не ясно, что произойдет, если вы запустите последние две команды. Ошибку легко объяснить на первом, dbms_output ограничен 32 КБ (раньше было 255 байт, но, к счастью, это было снято). Со вторыми двумя должно быть все в порядке. Не могли бы вы опубликовать точное сообщение об ошибке, которое каждый из них дает вам?

Paul W 15.02.2023 14:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

То, что вы говорите, не может быть правдой. DBMS_OUTPUT.PUT_LINE нельзя использовать на уровне SQL, он относится к PL/SQL.

  • Что такое MYPROC и что он содержит в строке №6?
  • Какой «редактор» «я могу выполнить в редакторе»?

Ошибка числа или значения обычно связана с тем, что вы пытаетесь сохранить «большие» значения в «маленькой» переменной:

SQL> declare
  2    l_var varchar2(2);
  3  begin
  4    l_var := 'ABC';
  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


SQL>

что, я полагаю, ты и сделал.


Другая причина - неправильно объявленная переменная, например.

SQL> declare
  2    l_var number;
  3  begin
  4    l_var := 'A';
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 4


SQL>

Я попытаюсь угадать, что вы можете делать:

SQL> set serveroutput on
SQL> DECLARE
  2     src  CLOB;
  3  BEGIN
  4     src := DBMS_METADATA.GET_DDL ('PACKAGE', 'MY_PKG', 'SCOTT');
  5     DBMS_OUTPUT.put_line ('len = ' || DBMS_LOB.getlength (src));
  6  END;
  7  /
len = 67239

PL/SQL procedure successfully completed.

SQL>

Как видите, у меня работает нормально. Пакет не такой уж и маленький (смотрите его длину), так что - не могу сказать, что вы сделали не так. Я предлагаю вам сделать то же самое, что и я: скопировать/вставить код, который я разместил выше (эти 7 строк), исправить информацию (функция, ее имя, владелец) и опубликовать результат, отредактировав исходный вопрос, а не как комментарий.

Действительно, я внес исправления и добавил больше информации в свой вопрос.

hajduk 15.02.2023 11:50

Я тоже так сделал; Посмотрите, пожалуйста.

Littlefoot 15.02.2023 12:29
Ответ принят как подходящий

Из документации для dbms_output:

Максимальный размер строки составляет 32767 байт.

Это означает, что вы не можете передать больше за один вызов put_line. В настоящее время вы передаете весь свой CLOB, который при 1290 строках, вероятно, превысит этот предел. И ошибка, которую вы получаете, когда вы это делаете, это «ORA-06502: PL/SQL: ошибка числа или значения», как вы видите.

Вы можете разделить свой CLOB на более мелкие фрагменты, и, поскольку он уже состоит из нескольких строк, имеет смысл сделать каждый фрагмент отдельной строкой из DDL. Вы можете сделать это, ища символы новой строки, извлекая весь текст до следующего и печатая его. Вам нужно несколько переменных, чтобы отслеживать, где вы находитесь. Что-то вроде этого должно работать для вас:

declare
  src clob;
  src_length pls_integer;
  pos pls_integer := 1;
  buffer varchar2(32767);
  amount pls_integer := 32767;
begin
  src := dbms_metadata.get_ddl('FUNCTION', 'TEST_FUNCTION_1', user);
  src_length := dbms_lob.getlength(src);

  while pos < src_length loop
    -- read to next newline if there is one, rest of CLOB if not
    if dbms_lob.instr(src, chr(10), pos) > 0 then
      -- see how many charcaters there are until next newline
      amount := dbms_lob.instr(src, chr(10), pos) - pos;
      -- if there are any, read them into the buffer; otherwise clear it
      if amount > 0 then
        dbms_lob.read(src, amount, pos, buffer);
      else
        buffer := null;
      end if;
      pos := pos + amount + 1; -- skip newline character
    else
      -- no newline so read everything that is left
      amount := 32767;
      dbms_lob.read(src, amount, pos, buffer);
      pos := pos + amount;
    end if;

    dbms_output.put_line(buffer);
  end loop;
end;
/

Это не сработает, если у вас есть одна строка (без новой строки в конце или без нее), размер которой превышает 32 КБ, что, надеюсь, не будет проблемой с DDL. (Вы могли бы справиться с этим, но это привело бы к добавлению дополнительных строк новой строки, что тоже было бы нехорошо.)

Другие вопросы по теме