2016-02-29 155 views
5

今日はすべて特別な日です。その29th of February 2016うるう年Oracle DB Ora-01839:指定された月に日付が無効です。 29-02-2016うるう年

Oracle DBの一部のテーブルからエラーメッセージが表示されます。エラーはOracle ORA-01839: date not valid for month specifiedです。例えば

簡単なエラーが発生した場所を選択:他のテーブルの場合select * from table where table_date > sysdate -0.1;

この選択はちょうどテーブルのいくつかのために、何の問題になりません。

この問題を解決する方法はありますか?今日は多くのテーブルを使用することができないためです。

Oracle 12cを使用しています。

+1

「table_date」列のデータ型は? –

+0

@WernfriedDomを 'date'に設定する – Patrick

+1

' select table_date from ... 'もそのエラーを受け取りますか?暗黙の変換に失敗した別の列かもしれませんか?テーブルまたはビュー(何かを計算する)ですか?またはそれは仮想列を持っていますか?エラーを受け取るセッション内のNLS_DATE_FORMATは何ですか?あなたは特定のクライアントでこれを見ていますか?SQL \ * Plusで再現できますか? –

答えて

7

今日、集中的な調査の結果、私たちの選択の一部が今日は機能しない理由は明らかです。このエラーは、キーワードintervalとその既知の問題によって発生します。

質問

select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' year as dt from dual; 

ORA-01839: date not valid for month specified 
01839. 00000 - "date not valid for month specified" 
*Cause:  
*Action: 

select to_date('2012-feb-29','yyyy-mon-dd') + interval '2' year as dt from dual; 

ORA-01839: date not valid for month specified 
01839. 00000 - "date not valid for month specified" 
*Cause:  
*Action: 

select to_date('2012-feb-29','yyyy-mon-dd') + interval '3' year as dt from dual; 

ORA-01839: date not valid for month specified 
01839. 00000 - "date not valid for month specified" 
*Cause:  
*Action: 

select to_date('2012-feb-29','yyyy-mon-dd') + interval '4' year as dt from dual; 

29-FEB-16 00:00:00 


select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' day as dt from dual; 

01-MAR-12 00:00:00 

select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' month as dt from dual; 

29-MAR-12 00:00:00 

回答ここ

oracle community blogからqouteである(またはそれは、ANSI/ISO specは、それが動作するはずと言うかのページ206ページ205 /トップの下です)

これは、インターバルの仕組みです。うるう年は 問題の中で最も少なくなります。 3月31日に1ヶ月追加すると、同じエラーが発生します。 の結果が有効なDATEであることを確認したい場合は、 ADD_MONTHSを使用してください。 (年を追加するための独立した機能はありません。今からn個の年であるDATEを取得するために ADD_MONTH(SYSDATE、12 * n)を使用します。)

それが私たちの場合に起こるのはなぜ

私たちのケースでは、セキュリティ上の理由から、いくつかのテーブルで仮想プライベートデータベースを使用しました。そしてそこでは、ほとんどの選択項目でintervalキーワードを適用しました。

代わりに何をすべきか:代わりに

使用ADD_MONTHS

select add_months(to_date('2012-feb-29','yyyy-mon-dd'), 12) as dt from dual; 
+3

夏時間の場合は、動作も異なります。 'TIMESTAMP 'を比較してください2015-10-25 01:30:00ヨーロッパ/ベルリン' + INTERVAL '1月'対ADD_MONTHS(TIMESTAMP '2015-10-25 01:30:00ヨーロッパ/ベルリン'、1)' –

+0

私たちは間違いなく次のようなコードを持っていました(これは、今日のODP.NETにINTERBALを 'DbFunctions.AddYears'で使用しているため、このOracle例外が発生しました)。 ' DataSet.Where(e => e.Date> = DbFunctions.AddYears今、-1)) ' – Trent

+0

ありがとうございます。あなたが月の境界を越えて閏年をサポートするつもりがないなら、日付+間隔をサポートすることのポイントは何ですか? –

関連する問題