将TO_CHAR值分配给VARCHAR失败

时间:2013-06-11 12:36:56

标签: oracle plsql

我在下面的函数中得到数字或值错误

在以下一行

acutalStartTime:=TO_CHAR (startTime, 'yyyy-mm-dd ');

任何人都可以告诉我什么可能是错的,如果我能写出更好的方法,有人也可以告诉我吗?

create or replace function dateDiff 
  ( changeInStartTime out varchar2,acutalStartTime out varchar2 )
RETURN timestamp
IS
  startTime timestamp;
  v_start   timestamp;
  diffdays number;
  findiff  BOOLEAN;
  diff number;

  cursor c1 is
  SELECT sometime from sometable;

BEGIN

  changeInStartTime:='false';
    v_start := TRUNC (SYSTIMESTAMP) + NUMTODSINTERVAL (1, 'second'); 
    open c1;
    fetch c1 into startTime;

      Dbms_Output.Put_Line('value of query ' ||startTime);

    if c1%notfound then
        startTime := TO_TIMESTAMP('2012-01-01 00:00:00.001','yyyy-mm-dd hh24:mi:ss .ff3');
 findiff:=false;

   else findiff:=true;
    end if;

 --Dbms_Output.Put_Line('should we find diff' || findiff);

    if findiff then
      Dbms_Output.Put_Line('v_start ' || v_start);
      Dbms_Output.Put_Line('startTime ' || startTime);

         diff :=trunc(v_start) - trunc(startTime) ;
      --diffdays:=extract(day from diff);

      Dbms_Output.Put_Line('diff ' || diff);
      Dbms_Output.Put_Line('diffdays ' || diffdays);

    if diff > 1 then
        changeInStartTime:='true';

        startTime:=TRUNC (SYSTIMESTAMP-diff ) + NUMTODSINTERVAL (1, 'second'); 
    else startTime:=v_start;
    end if;

    close c1;

  end if;
  acutalStartTime:=TO_CHAR (startTime, 'yyyy-mm-dd ');
    RETURN startTime;

    EXCEPTION
WHEN OTHERS THEN
    raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;

4 个答案:

答案 0 :(得分:2)

它可能是文字末尾的空格吗?

acutalStartTime:=TO_CHAR (startTime, 'yyyy-mm-dd ');
--                                              ^

这使得返回值长11个字符,并且调用代码中的变量可能被定义为VARCHAR2(10)?

答案 1 :(得分:2)

我使用以下代码来调用dateDiff

declare
  datum varchar2(20);
  cist varchar2(20);
  ret timestamp;
begin
  ret := dateDiff(cist, datum);
end;
/

匿名代码块已完成且没有错误。

问题必须出在调用代码中。检查参数是否为varchar2类型,并且大到足以保存返回值。

答案 2 :(得分:2)

我猜您收到此错误消息:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 22
06502. 00000 -  "PL/SQL: numeric or value error%s"

如果调用程序的VARCHAR2变量太短,则可以重现。

这是一个证明它的测试程序:

set serveroutput on
declare
  diff            number := 1;
  startTime       timestamp;    
  acutalStartTime varchar2(100);
  shortStartTime  varchar2(1);
begin
  dbms_output.put_line('Start');

  startTime:=TRUNC (SYSTIMESTAMP-diff ) + NUMTODSINTERVAL (1, 'second');
  dbms_output.put_line(startTime);

  -- WORKS BECAUSE VARCHAR IS LONG ENOUGH 
  ----------------------------
  acutalStartTime:=TO_CHAR (startTime, 'yyyy-mm-dd ');
  dbms_output.put_line(acutalStartTime);

  -- CRASHING STATEMENT
  ----------------------------
  shortStartTime:=TO_CHAR (startTime, 'yyyy-mm-dd ');
  dbms_output.put_line(shortStartTime);

  dbms_output.put_line('End');
end;
/

输出:

Error report:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 19
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    
*Action:
Start
10-JUN-13 12.00.01.000000 AM
2013-06-10 

确保您的调用例程有足够长的VARCHAR2

答案 3 :(得分:1)

在函数中使用OUT参数被特别称为Oracle documentation中的错误做法。

  
    

不要将OUT和IN OUT用于功能参数。理想情况下,函数接受零个或多个参数并返回单个值。具有IN OUT参数的函数返回多个值并具有副作用。

  

所以你可能想先弄清楚这是一个函数还是一个过程。