0

以下のクエリを実行しようとしていますが、このエラーが発生します:

to_date ora-01847 day of month must be between 1 and last day of month

クエリは、2つの異なるテーブルで日付と時刻の重複をチェックすることです

table1 (emp_num1 number,start_date1 date,start_time1 varchar2,end_date1 date,end_time2 varchar2)

table2(emp_num2 number,start_date2 date,start_time2 varchar2,end_date2 date,end_time2 varchar2)

select *
  from table1 t1
      ,table2 t2
 where t1.emp_num 1 = t2.emp_num2
   and to_timestamp(to_char(start_date1,'DD-MON-YYYY')||' '||NVL(start_time1,'00:00'),'DD-MON-YYYY HH24:MI')
       between
      to_timestamp(to_char(start_date2,'DD-MON-YYYY')||' '||NVL(start_time2,'00:00'),'DD-MON-YYYY HH24:MI')
       and
      to_timestamp(to_char(end_date2,'DD-MON-YYYY')||' '||NVL(end_time2,'00:00'),'DD-MON-YYYY HH24:MI')
      or
      to_timestamp(to_char(end_date1,'DD-MON-YYYY')||' '||NVL(end_time1,'00:00'),'DD-MON-YYYY HH24:MI')
       between
      to_timestamp(to_char(start_date2,'DD-MON-YYYY')||' '||NVL(start_time2,'00:00'),'DD-MON-YYYY HH24:MI')
       and
      to_timestamp(to_char(end_date2,'DD-MON-YYYY')||' '||NVL(end_time2,'00:00'),'DD-MON-YYYY HH24:MI')

上記のクエリの結果、エラーが発生しました。

to_date ora-01847 day of month must be between 1 and last day of month

クエリを実行してみました

select to_timestamp(to_char(start_date1,'DD-MON-YYYY')||' '||NVL(start_time1,'00:00'),'DD-MON-YYYY HH24:MI') from table1

エラーは発生しません。

4

2 に答える 2

2

エラーを再現するには:

SELECT NVL(SYSDATE,'00:00')
FROM DUAL

ORA-01847: 日は 1 から月末日までの間である必要があります

NVL() の説明には次のように書かれています。

引数 expr1 および expr2 は、任意のデータ型を持つことができます。データ型が異なる場合、Oracle Databaseは暗黙的に一方を他方に変換します。暗黙的に変換できない場合、データベースはエラーを返します。暗黙的な変換は次のように実装されます。

  • expr1 が文字データの場合、Oracle Databaseは expr2 を比較する前に expr2 を expr1 のデータ型に変換し、 expr1 のキャラクタ・セットで VARCHAR2 を戻します。

  • expr1 が数値の場合、Oracle Databaseは数値の優先順位が最も高い引数を判別し、他の引数をそのデータ型に暗黙的に変換して、そのデータ型を返します。

したがって、再現ケースを単純化できます。

SELECT TO_DATE('00:00')
FROM DUAL

形式を指定していないため、 を想定しNLS_DATE_FORMATているため、エラー: '00' は有効な日ではありません。

(何をしようとしているのかはよくわかりませんが、純粋な日付関数を使用してみてください。)

于 2013-03-07T18:02:18.903 に答える
0

フォーマットを修正する必要があります。初期設定は次のとおりです。

SELECT '07-MAR-2013' start_date -- char
     , NULL          start_time -- char
 FROM dual
/

最終フォーマット-NVLは必要ありません。ただし、NVL(start_time、 '00:00')を追加する必要がある場合は、次のようにします。

SELECT to_timestamp(start_date||' '||start_time, 'DD-MON-YYYY HH24:MI:SS') t_stamp
  FROM
  (
   SELECT '07-MAR-2013'      start_date -- char
        , NVL(NULL, '00:00') start_time -- char - NVL is optional 
    FROM dual
  )
 /

 3/7/2013 12:00:00.000000000 AM

start_time complを削除しても、同じ結果が得られます。通常、日付を比較するには、TRUNCを使用して時間部分を削除する必要があります。

SELECT to_timestamp('07-MAR-2013', 'DD-MON-YYYY HH24:MI:SS') start_date_only 
  FROM dual
/   

3/7/2013 12:00:00.000000000 AM

 SELECT trunc(to_timestamp('07-MAR-2013', 'DD-MON-YYYY HH24:MI:SS')) start_date_only FROM dual
 /

3/7/2013
于 2013-03-07T19:47:26.447 に答える