oracle10201 plsql 中max的Ora-06502异常

先看例子:
SQL> select * from v$version;
 
BANNER
----------------------------------------------------------------
Personal Oracle Database 10g Release 10.2.0.1.0 - Production
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
 
SQL>
SQL> declare
  2      v_x varchar2(10);
  3  begin
  4      select max('1')
  5        into v_x
  6        from dual;
  7  end;
  8  /
 
declare
    v_x varchar2(10);
begin
    select max('1')
      into v_x
      from dual;
end;
 
ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小
ORA-06512: 在 line 5
 可以看到,使用max时,出现了该异常。
开始看到这个现象的时候,以为是变量定义范围太小的缘故。但是从同事那边来看,如果是这么简单,应该他早就发现了。所以我想应该不能从这个方向去解决问题。所以我尝试使用直接字符串1来替换max中的内容,这样v_x这个变量的范围肯定可以容下这个字符串了。结果即在意料之外,又在意料之中。意料之外是1这样的字符串也抛出了异常。如果是a这样的字符,还有点道理。但是1却没有料到。意料之中是这个问题的确不像我之前所说的那么简单。
于是我考虑是不是max在plsql中取值的时候都是按照数字来转换的,而不会做默认的转换,只要遇到字符串就抛出该异常。因此我尝试用to_char转换:
SQL> declare
  2      v_x varchar2(10);
  3  begin
  4      select max(to_char('1'))
  5        into v_x
  6        from dual;
  7  end;
  8  /
 
PL/SQL procedure successfully completed
发现是可以的。但是进一步的检查发现:
SQL> declare
  2      v_x varchar2(10);
  3  begin
  4      select to_char(max('1'))
  5        into v_x
  6        from dual;
  7  end;
  8  /
 
PL/SQL procedure successfully completed
to_char放在外面也是可以的。这个就搞不懂了。经过google,发现这原来是oracle10g的一个bug,当max中的数据类型是char时就会抛出这个异常,但是如果是varchar2就不会有该异常,在9i上测试没有该问题。
转成varchar2后的测试:
SQL> declare
  2      v_x varchar2(10);
  3  begin
  4      select max(cast('1' as varchar2(10)))
  5        into v_x
  6        from dual;
  7  end;
  8  /
 
PL/SQL procedure successfully completed
实际上to_char也是将对应的字符串转成varchar2。
该问题对应的bug#4458790

请使用浏览器的分享功能分享到微信等