oracle ORA-06502与ORA-06512

beq87vna  于 2023-02-18  发布在  Oracle
关注(0)|答案(2)|浏览(333)

我有一个过程,在这个过程中,我试图向dbms_output编写一个源代码(1290行),如下所示:

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中。我可以在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

有线索吗?

b4qexyjb

b4qexyjb1#

来自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 k,那么它就不起作用了,希望这不会成为DDL的问题(您可以处理这个问题,但是这样做会注入额外的换行符,这也不好)。

mu0hgdu0

mu0hgdu02#

你说的不可能是真的。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行),修复信息(函数,它的名称,所有者),并通过编辑原始问题发布结果,而不是作为注解。

相关问题