1

YEAR TO MONTH値に間隔を追加した場合があり、TIMESTAMPこれを達成するためにこのように使用しています

SELECT (END_DATE + NUMTOYMINTERVAL(2, 'MONTH')) FROM DUAL

上記のコードは、特定の値を除くほぼすべての END_DATE 値に対して正常に機能します。

たとえば、END_DATE = 31-JULY-2013上記のコードの期待される結果は30-SEPT-2013エラーになりますが、

ORA-01839: date not valid for month specified

これは、上記のコードが31-SEPT-2013無効な日付を返すためです。

これを達成する別の方法はありますか?

(使用できますADD_MONTHSが、この関数を使用すると、値のみが返され、戻り値としてDATE必要TIMESTAMPです)

私は何か不足していますか?

4

3 に答える 3

2

これは、ANSI で指定されている予期される動作です。この AskTomを参照してください。2013 年 7 月 30 日に 2 か月足すと、2013 年 9 月 30 日になります。これは完全に理解できると思います。2013 年 7 月 31 日に 2 か月を追加すると、次のようになります。2013 年 9 月 31 日はありません。9 月は 30 日しかありません。では、システムは何をするべきなのでしょうか? 2013 年 9 月 30 日になるはずですか?2013 年 10 月 1 日と表示されますか? これらはどちらも正しくありません。月の値を 2 か月前に変更するように要求しました。OK、それを試みて、結果の日付が無効であることを発見したため、エラーがスローされます。

まあ。

しかし、ありがたいことに、私たちは単なる人間ではありません。私たちは優れた存在です。私たちはソフトウェア開発者です。マニュアルがあります!!!! 私たちは神々の近くにいます!!!!!!!!!!!!

そこで、マニュアルを参照すると、ADD_MONTHS 関数が利用可能であることがわかります。これは、ここで探しているほとんどのことを実行します。ただし、ADD_MONTHS は DATE 値でのみ動作するため、保存するために余分な操作を行わないと、小数秒が失われます。しかし、私が言ったように、私たちはソフトウェア開発者です...

例:

DECLARE 
  tsIn  TIMESTAMP := TO_TIMESTAMP('31-JUL-2013 17:31:01', 'DD-MON-YYYY HH24:MI:SS');
  tsOut TIMESTAMP;
  nFrac_secs  NUMBER;
  strBuffer   VARCHAR2(1000);
  strFrac_secs VARCHAR2(1000);
BEGIN
  tsIn := tsIn + NUMTODSINTERVAL(0.1234, 'SECOND');

  strBuffer := TO_CHAR(tsIn);
  strFrac_secs := SUBSTR(strBuffer, -10, 7);

  DBMS_OUTPUT.PUT_LINE('tsIn=' || tsIn);
  DBMS_OUTPUT.PUT_LINE('strBuffer=' || strBuffer);
  DBMS_OUTPUT.PUT_LINE('strFrac_secs=' || strFrac_secs);

  nFrac_secs := TO_NUMBER(strFrac_secs);

  DBMS_OUTPUT.PUT_LINE('nFrac_secs=' || nFrac_secs);

  tsOut := ADD_MONTHS(tsIn, 2);

  DBMS_OUTPUT.PUT_LINE('tsOut before restoring fractional seconds=' || tsOut);

  tsOut := tsOut + NUMTODSINTERVAL(nFrac_secs, 'SECOND');

  DBMS_OUTPUT.PUT_LINE('tsOut after restoring fractional seconds=' || tsOut);
END;

したがって、基本的に、区間演算を実行しようとすると、Oracle は&^#@$# ANSI 仕様に従い、ばかげた動作をします。次に、多かれ少なかれ必要なことを行う関数(公平を期すために文書化されています)を提供しますが、DATE値に対してのみ行います。これがいわゆる「職安」だと思いますが…

:-)

共有してお楽しみください。

于 2013-07-11T11:27:08.920 に答える