繁体   English   中英

Oracle - ORA-06502:PL / SQL:数值或值错误(DBMS_OUTPUT)

[英]Oracle - ORA-06502: PL/SQL: numeric or value error (DBMS_OUTPUT)

我实现了一个返回clob数据类型的函数,我想在DBMS输出中打印结果。 不幸的是,我得到ORA-06502:PL / SQL:数字或值错误 ,我认为这是由于DBMS_OUTPUT的大小。

这是代码。

DECLARE

    TYPE tp_col_array IS TABLE OF varchar2(32767); 
    FUNCTION my_fn (        
        p_in_proc_date IN varchar2)
        RETURN clob AS         
         vr_output_str clob;

        BEGIN            

        -- Detailed code hidden due to privacy. Sorry

        RETURN vr_output_str;

        EXCEPTION 
            WHEN LOGIN_DENIED
            THEN 
                DBMS_OUTPUT.PUT_LINE('Invalid username/password: logon denied');
        RETURN 'TEST Terminated';

    END my_fn;

BEGIN
    DBMS_OUTPUT.PUT_LINE(my_fn('31-AUG-14'));    
END;

这些内容可以帮助您理解这个问题
1)添加以下内容来设置缓冲区的大小无限制 ,但没有工作..

DBMS_OUTPUT.ENABLE(NULL);

要么

set serveroutput on size unlimited;

相关链接: http//www.oracle-developer.net/display.php?id = 327

2)值得注意的是,vr_output_str的大小是75387,这就是为什么返回类型为CLOB。

DBMS_LOB.getlength(vr_output_str); // =75387

3)我可以通过以下方式解决问题,但我认为这不是一个好的解决方案,因为它执行了三次函数。

DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 1, 32767));
DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 32768, 32767));
DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 65536, 32767));

4)我使用的是Oracle Database 11g企业版11.2.0.3.0版 - 64位生产版

如果大于32767字节,则无法使用dbms_output.put_line直接打印clob。

如果是这种情况,您可以创建一个过程来迭代clob并一次打印出一个较小的块。 这样的程序和测试脚本如下:

declare 

  c clob;

  procedure print_clob( p_clob in clob ) is
      v_offset number default 1;
      v_chunk_size number := 10000;
  begin
      loop
          exit when v_offset > dbms_lob.getlength(p_clob);
          dbms_output.put_line( dbms_lob.substr( p_clob, v_chunk_size, v_offset ) );
          v_offset := v_offset +  v_chunk_size;
      end loop;
  end print_clob;


begin
  for i in 1..10000 loop
     c := c || 'test';
  end loop;
  --This will result in ora-06502
  --dbms_output.put_line(c);

  print_clob(c);

end;

请注意,v_chunk_size必须导致少于32767个字节一次被分块。 如果编码每个字符有2个字节,则需要使用(32767/2)。

以下程序将更好:

  • Oracle 10g对put_line有限制(最多32767个字符),但10g之前的Oracle最多有255个字符限制。
  • 'put_line'在输出clob期间的每个迭代循环上添加行尾。 所以我们更好地使用put()(最后使用'DBMS_OUTPUT.NEW_LINE')。
PROCEDURE print_clob( p_clob in clob ) IS
        v_offset number default 1;
        v_chunk_size number := 255; 
      BEGIN
        LOOP
          EXIT when v_offset > dbms_lob.getlength(p_clob);
          dbms_output.put( dbms_lob.substr( p_clob, v_chunk_size, v_offset ) );
          v_offset := v_offset +  v_chunk_size;
        END LOOP;
        DBMS_OUTPUT.NEW_LINE;  
      END print_clob;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM