【问题标题】:Error: ORA-06502: PL/SQL: numeric or value error: host bind array too small错误:ORA-06502:PL/SQL:数字或值错误:主机绑定数组太小
【发布时间】:2017-10-03 04:25:50
【问题描述】:

我想了解这个oracle错误何时发生'错误:ORA-06502:PL/SQL:数字或值错误:主机绑定数组太小'

我有一个 plsql 块,它有一个普通的匿名块,它有 DBMS_output.put_line 并且在 for 循环中也有 DBMS_output.put 并且在代码中它在 for 循环本身中调用另一个包以及像成功这样的输出变量(如S) 和包的错误消息(如 err_msg)使用 DBMS_output.put 显示,并且输出被打印为很少的记录,但突然发生上述错误并且块被完成,这不是怎么发生的。谁能解释为什么会发生这种错误。

【问题讨论】:

  • 什么版本的 Oracle 和 SQL/Plus?有关相同问题,请参阅 this discussion - 在 Oracle 9i(或使用早期 SQL/Plus 版本访问的更高 Oracle 版本)中,DBMS_OUTPUT.PUT_LINE 似乎有 255 个字符的限制。

标签: oracle plsql


【解决方案1】:

错误发生在客户端,而不是服务器端,所以这是sqlplus的特定版本的错误。当sqlplus 实用程序尝试将dbms_output 缓冲区从服务器端读取到客户端缓冲区时,会发生这种情况,并且该缓冲区包含一个长度超过 255 个字符的字符串。所以错误发生在:

  1. 您正在使用版本低于 10.2 的 sqlplus,并且数据库服务器的版本为 10.2 或更高版本。例如:
    1. 客户端是10.1.0.5,服务器是12.2.9
    2. 客户端是10.1.0.5,服务器是10.2.0.5
    3. 客户端是10.1.0.5,服务器是11.2.0.1
  2. serveroutput on 选项已设置
  3. 您已将超过 255 个字符的行放入 dbms_output 缓冲区。

请注意,如果您的服务器是 10.1.0.5 或更低版本 (9.2.0.8),您会收到不同的错误:ORA-20000: ORU-10028: line length overflow, limit of 255 chars per line

演示

输入 256 个字符,我们得到错误:

SET SERVEROUTPUT ON
begin
  dbms_output.put_line(a => rpad('1',256,'1'));
end;
/
ERROR:
ORA-06502: PL/SQL: numeric or value error: host bind array too small
ORA-06512: at line 1

或者你可以用稍微不同的方式来做:

SET SERVEROUTPUT ON
begin
  dbms_output.put(a => rpad('1',200,'1'));
  dbms_output.put(a => rpad('1',200,'1'));
  dbms_output.put_line('');
end;
/
ERROR:
ORA-06502: PL/SQL: numeric or value error: host bind array too small
ORA-06512: at line 1

输入 255 个字符,就可以得到输出了:

SET SERVEROUTPUT ON
begin
  dbms_output.put_line(a => rpad('1',255,'1'));
end;
/
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111

如何解决

选项 1:

Oracle 在 10.2 版本中修复了该错误,因此如果您将服务器端和客户端组件升级到至少 10.2.0.5,该错误将得到修复。

选项 2:

如果您必须使用 10.1 或更早版本的 sqlplus(并且数据库版本为 10.2 或更高版本)并且您无法重写生成长字符串的 pl/sql 代码,那么您可以解决此错误使用dbms_output.get_lines(或dbms_output.get_line)程序:

SET SERVEROUTPUT OFF
begin
  -- enable the server-side buffer. When SET SERVEROUTPUT ON sqlplus does it automatically.
  -- Now we do it manually.
  dbms_output.enable(1000000);
  
  dbms_output.put_line(a => rpad('1',300,'1'));
end;
/
PL/SQL procedure successfully completed.

然后使用这个块来获取缓冲区的内容:

variable l_cursor REFCURSOR
set autoprint on
declare
  -- Then use this block to get the contents of the buffer.
  l number:=10000;
  l_array DBMSOUTPUT_LINESARRAY;
begin
  dbms_output.get_lines(l_array,l);
  open :l_cursor for select * from table(l_array);
end;
/

PL/SQL procedure successfully completed.

COLUMN_VALUE
--------------------------------------------------------------------------------
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111

【讨论】:

    【解决方案2】:

    通常当您尝试设置一个值太大的变量时会发生此错误。例如。

    v_number number(2);
    BEGIN
      v_number := 100;
    END;
    

    或者当您尝试将文本保存到数字变量中时

    v_number number(2);
    BEGIN
      v_number := 'a';
    END;
    

    查看这里了解更多信息:https://www.techonthenet.com/oracle/errors/ora06502.php

    【讨论】:

    • OP 的错误是ORA-06502: PL/SQL: numeric or value error: host bind array too small 而不是ORA-06502: PL/SQL: numeric or value error: number precision too largeORA-06502: PL/SQL: numeric or value error: character to number conversion error
    • 我能够复制该问题。在 SQL PLUS 中,dbms_output.put_line 限制为最多 255 个字符。如果超出此限制,则会弹出“错误:ORA-06502:PL/SQL:数字或值错误:主机绑定数组太小”。但这不会影响块的执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 2011-03-31
    • 2016-12-18
    • 1970-01-01
    • 2013-09-14
    相关资源
    最近更新 更多