本文记录了Oracle存储过程常见的两种字符串缓冲区太小报错原因,希望能帮到研发测试进行问题排查:

问题一

存储过程中定义的字段太小,实际传入值长度大于定义长度:

create or replace procedure delete_datas
   (
     --In_ERPORDER  IN VARCHAR,
     OUT_Return_Code OUT VARCHAR)
IS
   r_dd_timer varchar2(2);
   BEGIN
       select '43324324' into r_dd_timer from dual;
       OUT_Return_Code:='000';
   EXCEPTION
      WHEN OTHERS THEN
      DBMS_OUTPUT.put_line(SUBSTR(DBMS_UTILITY.format_error_backtrace, 1, 10000));
      rollback;
      OUT_Return_Code:='999'||SQLerrm || DBMS_UTILITY.format_error_backtrace;
   END;

问题二

v_dname 是定义的变量,类型使用%type,参照的表dept.dname(长度比如8位),当tmp_dept 表的v_dname长度10位,传入v_dname 时,也会报: 数字或值错误 : character string buffer too small

CREATE OR REPLACE 
procedure getDeptById
(
v_deptno in dept.deptno%type
)
is
v_dname dept.dname%type;
v_loc dept.loc%type;
begin
select dname,loc into v_dname,v_loc from tmp_dept where deptno = v_deptno;
dbms_output.put_line(v_dname||'***'||v_loc);
end;

问题三

存储过程调用的存储过程中返回的字段长度超过定义的长度,这种返回参数比较多的时候,较难定位,需要一个个排查,这里给出一个案例:

create or replace procedure SP_COUNT_RANDOM(IN_WarehouseID  in Varchar2,
                                                   IN_Language     in varChar2,
                                                   IN_UserID       in varChar2,
                                                   OUT_Return_Code in out varChar2) IS
  r_CCTaskID     varchar(10);  
begin  
      SPCOM_GetIDSequence(IN_WarehouseID, in_Language, 'TaskID', R_CCTaskID, Out_Return_Code);
  OUT_Return_Code := '000';
  return;

EXCEPTION
  WHEN OTHERS THEN
    OUT_Return_Code := '999' || IN_WarehouseID || '#' ||
                       'SP_UDF_SF_COUNT_RANDOM' || SQLerrm ||
                       DBMS_UTILITY.format_error_backtrace;
    ROLLBACK;
end;      
                                                 

被调用存储过程

create or replace procedure SPCOM_GetIDSequence
( IN_Warehouse              in varchar2,
  IN_Language               in varChar2,
  IN_Sequence_Name_C        in varchar2,
  OUT_ReturnNo              out varchar2,
  OUT_Return_Code           in out varchar2)
is
  R_Length          int;
  R_Date_Str        varchar(8 char);    
begin
    OUT_ReturnNo := '12321321321';
    R_Length := 18
    r_Date_Str := null;
	OUT_ReturnNo := r_PreFix || r_Date_Str || lpad(OUT_ReturnNo, R_Length, '0');
   return;

EXCEPTION
   WHEN OTHERS THEN
      Out_Return_Code :='SYS_0199 SPCOM_GetIDSequence '||SQLerrm || DBMS_UTILITY.format_error_backtrace;
      ROLLBACK;
end;

此调用过程,SP_COUNT_RANDOM调用SPCOM_GetIDSequence,SPCOM_GetIDSequence返回字段OUT_ReturnNo长度18超过r_CCTaskID定义长度10,报错:SYS_0199 SPCOM_GetIDSequence ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小ORA-06512: 在 “SPCOM_GETIDSEQUENCE”, line XX处

解决方法

这两种字符串缓冲区太小问题,可通过加长字段定义长度解决。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐