0

我在以下函数中收到数字或值错误

在以下行

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

4 回答 4

2

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

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

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

于 2013-06-11T13:06:33.503 回答
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

于 2013-06-11T19:20:39.273 回答
2

我使用以下代码调用dateDiff

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

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

问题一定出在调用代码中。检查参数的类型varchar2和大小是否足以容纳返回值。

于 2013-06-11T15:06:45.050 回答
1

在 Oracle文档中特别指出在函数中使用 OUT 参数是不好的做法。

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

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

于 2013-06-11T20:12:06.080 回答