美文网首页
ORA-20000: ORU-10027: Buffer Ove

ORA-20000: ORU-10027: Buffer Ove

作者: 磐石数据 | 来源:发表于2020-12-02 13:53 被阅读0次

    业务自动化任务报出:

    DECLARE
    *
    ERROR at line 1:
    ORA-20000: ORU-10027: buffer overflow, limit of 1000000 bytes
    ORA-06512: at "SYS.DBMS_OUTPUT", line 32
    ORA-06512: at "SYS.DBMS_OUTPUT", line 97
    ORA-06512: at "SYS.DBMS_OUTPUT", line 112
    ORA-06512: at line 157
    

    一般情况下可以通过

    exec dbms_output.enable(size)
    size:2000 .. 1000000
    

    最大输出结果长度不能超过1000000。

    根据文档,从Oracle 10g开始,支持无限输出,可以采用如下设置:

    exec dbms_output.enable(buffer_size=>null)
    

    对于Oracle 10g之前的版本,也可以通过一个小技巧来绕过最大1000000的限制。
    测试如下:
    错误模拟,设置buffer_size=>20000:

    SQL> 
    SQL> set serveroutput on
    SQL> DECLARE
      2     y1 varchar2(80);
      3     y2 number;
      4  BEGIN
      5     dbms_output.enable(buffer_size => 20000);
      6     --DBMS_OUTPUT.ENABLE (buffer_size => NULL);
      7     SELECT to_char(sysdate, 'hh-mi-ss')into y1 from dual;
      8  
      9     DBMS_OUTPUT.PUT_LINE(y1);
     10  
     11     y2 := 0;
     12     LOOP
     13        IF mod(y2,30) = 0 THEN
     14           --dbms_output.enable(20000);
     15           null;
     16       END IF;
     17  
     18        IF y2 > 100 THEN
     19           exit;
     20        END IF;
     21        y2 := y2 + 1;
     22       dbms_output.put_line(rpad(to_char(y2)||'-->',200,'s'));
     23     END LOOP;
     24  
     25     SELECT to_char(sysdate, 'hh-mi-ss') into y1 from dual;
     26  
     27     DBMS_OUTPUT.PUT_LINE(y1);
     28     --dbms_output.disable;
     29  
     30  END;
     31  /
    
    11-13-56
    1-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    2-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    3-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    ...省略4-->~97-->行内容...
    98-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    99-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    DECLARE
       y1 varchar2(80);
       y2 number;
    BEGIN
       dbms_output.enable(buffer_size => 20000);
       --DBMS_OUTPUT.ENABLE (buffer_size => NULL);
       SELECT to_char(sysdate, 'hh-mi-ss')into y1 from dual;
    
       DBMS_OUTPUT.PUT_LINE(y1);
    
       y2 := 0;
       LOOP
          IF mod(y2,30) = 0 THEN
              --dbms_output.enable(20000);
              null;
          END IF;
    
          IF y2 > 100 THEN
             exit;
          END IF;
          y2 := y2 + 1;
          dbms_output.put_line(rpad(to_char(y2)||'-->',200,'s'));
       END LOOP;
    
       SELECT to_char(sysdate, 'hh-mi-ss') into y1 from dual;
    
       DBMS_OUTPUT.PUT_LINE(y1);
       --dbms_output.disable;
    
    END;
    
    ORA-20000: ORU-10027: buffer overflow, limit of 20000 bytes
    ORA-06512: at "SYS.DBMS_OUTPUT", line 32
    ORA-06512: at "SYS.DBMS_OUTPUT", line 97
    ORA-06512: at "SYS.DBMS_OUTPUT", line 112
    ORA-06512: at line 22
    

    解决方法1:设置buffer_size=>null

    SQL> set serveroutput on
    SQL> DECLARE
      2     y1 varchar2(80);
      3     y2 number;
      4  BEGIN
      5     --dbms_output.enable(buffer_size => 20000);
      6     DBMS_OUTPUT.ENABLE (buffer_size => NULL);
      7     SELECT to_char(sysdate, 'hh-mi-ss')into y1 from dual;
      8  
      9     DBMS_OUTPUT.PUT_LINE(y1);
     10  
     11     y2 := 0;
     12     LOOP
     13        IF mod(y2,30) = 0 THEN
     14           --dbms_output.enable(20000);
     15           null;
     16       END IF;
     17  
     18        IF y2 > 100 THEN
     19           exit;
     20        END IF;
     21        y2 := y2 + 1;
     22       dbms_output.put_line(rpad(to_char(y2)||'-->',200,'s'));
     23     END LOOP;
     24  
     25     SELECT to_char(sysdate, 'hh-mi-ss') into y1 from dual;
     26  
     27     DBMS_OUTPUT.PUT_LINE(y1);
     28     --dbms_output.disable;
     29  
     30  END;
     31  /
    
    11-13-01
    1-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    2-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    3-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    ...省略4-->~97-->行内容...
    98-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    99-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    100-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    101-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    11-13-01
    
    PL/SQL procedure successfully completed
    

    解决方法2:小技巧

    SQL> set serveroutput on
    SQL> DECLARE
      2     y1 varchar2(80);
      3     y2 number;
      4  BEGIN
      5     dbms_output.enable(buffer_size => 20000);
      6     --DBMS_OUTPUT.ENABLE (buffer_size => NULL);
      7     SELECT to_char(sysdate, 'hh-mi-ss')into y1 from dual;
      8  
      9     DBMS_OUTPUT.PUT_LINE(y1);
     10  
     11     y2 := 0;
     12     LOOP
     13        IF mod(y2,30) = 0 THEN
     14           dbms_output.enable(20000);
     15           null;
     16       END IF;
     17  
     18        IF y2 > 100 THEN
     19           exit;
     20        END IF;
     21        y2 := y2 + 1;
     22       dbms_output.put_line(rpad(to_char(y2)||'-->',200,'s'));
     23     END LOOP;
     24  
     25     SELECT to_char(sysdate, 'hh-mi-ss') into y1 from dual;
     26  
     27     DBMS_OUTPUT.PUT_LINE(y1);
     28     --dbms_output.disable;
     29  
     30  END;
     31  /
    
    11-35-45
    1-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    2-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    3-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    ...省略4-->~97-->行内容...
    98-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    99-->sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    100-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    101-->ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    11-35-45
    
    PL/SQL procedure successfully completed
    

    方法2的小技巧为什么也能实现正常输出,基于dbms_output.enable中会对一些变量做初始化,通过跟踪dbms_output包内部实现可窥探一二:

    --dbms_output.enable
        IF BUFFER_SIZE < 2000 THEN
          BUF_SIZE := 2000;
        ELSIF BUFFER_SIZE > 1000000 THEN
          BUF_SIZE := 1000000;
        ELSIF BUFFER_SIZE IS NULL THEN
          BUF_SIZE := -1;   
        ELSE
          BUF_SIZE := BUFFER_SIZE;
        END IF;
        BUFLEFT := BUF_SIZE;
      
    --dbms_output.put_line
          STRLEN := NVL(LENGTHB(A), 0);
          IF ((STRLEN + LINEBUFLEN) > 32767) THEN
            LINEBUFLEN := 0; BUF(PUTIDX) := '';
            RAISE_APPLICATION_ERROR(-20000, 'ORU-10028: line length overflow, ' ||
              'limit of 32767 bytes per line');
          END IF;
    
          IF (BUF_SIZE <> -1) THEN   
            IF (STRLEN > BUFLEFT) THEN
                RAISE_APPLICATION_ERROR(-20000, 'ORU-10027: buffer overflow, ' ||
                  'limit of ' || TO_CHAR(BUF_SIZE) || ' bytes');
            END IF;
            BUFLEFT := BUFLEFT - STRLEN;
          END IF;
    

    在解决方法2中,在代码LOOP中根据一定条数设置dbms_output.enable(20000),可以让BUFLEFT满足输出要求,避免触发ORU-10027错误。

    相关文章

      网友评论

          本文标题:ORA-20000: ORU-10027: Buffer Ove

          本文链接:https://www.haomeiwen.com/subject/qrymwktx.html