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

次のコードを使用して呼び出しましたdateDiff

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

匿名コード ブロックはエラーなしで完了しました。

問題は呼び出し元のコードにあるはずです。パラメーターがvarchar2戻り値を保持するのに十分な型であり、十分な大きさであることを確認してください。

于 2013-06-11T15:06:45.050 に答える
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

リテラルの最後のスペースでしょうか?

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

これにより、戻り値は 11 文字になり、呼び出しコードの変数は VARCHAR2(10) として定義されているのではないでしょうか?

于 2013-06-11T13:06:33.503 に答える