Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2834175
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2011-09-27 17:32:05

同事遇到一个问题,执行了一个匿名PL/SQL块遇到ORA-06502错误。
简单重现一下:
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.
C:\Documents and Settings\yan>sqlplus admin/admin
SQL*Plus: Release 10.2.0.1.0 - Production on 星期二 9月 27 17:19:59 2011
Copyright (c) 1982, 2005, Oracle.  All rights reserved.

连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> set serverout on
SQL> declare
  2      lv_tmplevel  T_GCHKDEG.LEVNO%TYPE ;
  3  begin
  4      select levno into lv_tmplevel  from T_GCHKDEG where rownum=1;
  5      dbms_output.put_line(lv_tmplevel);
  6  end;
  7  /
01
PL/SQL 过程已成功完成。
SQL> declare
  2      lv_tmplevel  T_GCHKDEG.LEVNO%TYPE ;
  3  begin
  4     select min(levno) into lv_tmplevel  from T_GCHKDEG;
  5     dbms_output.put_line(lv_tmplevel);
  6  end;
  7  /
declare
*
第 1 行出现错误:
ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小
ORA-06512: 在 line 4

SQL> desc T_GCHKDEG
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 LEVNO                                     NOT NULL CHAR(2)
 LEVELTYPE                                          CHAR(1)
 RISKTYPE                                  NOT NULL CHAR(2)
 VALTYPE                                   NOT NULL CHAR(1)
 BEGNUM                                    NOT NULL NUMBER
 ENDNUM                                             NUMBER
 MINVALUE                                           NUMBER(12,2)
 MAXVALUE                                           NUMBER(12,2)
 BEGDATE                                   NOT NULL DATE
 ENDDATE                                   NOT NULL DATE
 GAVENO                                             CHAR(10)
 GAVEDATE                                           DATE
 MOVENO                                             CHAR(10)
 MOVEDATE                                           DATE
 LASTUPDOPER                                        CHAR(10)
 LASTUPDTRA                                         VARCHAR2(14)
 LASTUPDTIME                                        CHAR(14)
SQL> select min(levno) from T_GCHKDEG;
MI
--
01
SQL> select length(min(levno)) from T_GCHKDEG;
LENGTH(MIN(LEVNO))
------------------
                 2
LEVNO定义的是CHAR(2),MIN(LEVNO)也不可能会超出2个字符。
加了个TO_CHAR函数就能执行成功了。
SQL> declare
  2      lv_tmplevel  T_GCHKDEG.LEVNO%TYPE ;
  3  begin
  4     select to_char(min(levno)) into lv_tmplevel  from T_GCHKDEG;
  5     dbms_output.put_line(lv_tmplevel);
  6  end;
  7  /
01
PL/SQL 过程已成功完成。

查询了METALINK,发现是ORACLE的BUG。
Bug:4458790 ORA-6502 selecting MAX/MIN into a CHAR variable in PLSQL
SELECT containing a MIN or MAX into a CHAR variable inside a PL/SQL block Fails With ORA-06502 [ID 311653.1]
 

ORACLE给出了一下3种解决方法:
1、setting initialisation parameter BLANK_TRIMMING=TRUE

2、declare PL/SQL CHAR and VARCHAR2 variable used in the INTO clause of SELECT statement as 4,000 bytes.

3、se CAST SQL function to constraint the size to that of the variable size like
SELECT CAST(MIN('Y') AS CHAR(1)) INTO C FROM DUAL;
 

SQL> declare
  2      lv_tmplevel  char(4000) ;
  3  begin
  4     select min(levno) into lv_tmplevel  from T_GCHKDEG;
  5     dbms_output.put_line(lv_tmplevel);
  6  end;
  7  /
01
PL/SQL 过程已成功完成。

SQL> declare
  2      lv_tmplevel  T_GCHKDEG.LEVNO%TYPE ;
  3  begin
  4     select cast (min(levno) as char(2)) into lv_tmplevel  from T_GCHKDEG;
  5     dbms_output.put_line(lv_tmplevel);
  6  end;
  7  /
01
PL/SQL 过程已成功完成。
 
阅读(2766) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~