2013-03-07 108 views
0

我試圖執行下面的查詢的最後一天,但之間得到這個錯誤:TO_DATE ORA-01847個月日必須在1個月

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

查詢是檢查日期和時間的overlaping在兩個不同的表

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 

沒有遇到任何錯誤。

+1

是否有可能四個日期字段中的一個具有NULL值? – 2013-03-07 17:08:20

+0

嘗試用NULL代替'​​start_date1'的測試查詢:我敢打賭它給出了同樣的錯誤。 – wallyk 2013-03-07 17:15:07

+0

日期字段是必填字段...因此,沒有任何表格具有空日期文件夾 – rocky 2013-03-07 17:30:37

回答

2

要重現錯誤:

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

ORA-01847: day of month must be between 1 and last day of month

NVL() description說:

The arguments expr1 and expr2 can have any data type. If their data types are different, then Oracle Database implicitly converts one to the other. If they cannot be converted implicitly, then the database returns an error. The implicit conversion is implemented as follows:

  • If expr1 is character data, then Oracle Database converts expr2 to the data type of expr1 before comparing them and returns VARCHAR2 in the character set of expr1.

  • If expr1 is numeric, then Oracle Database determines which argument has the highest numeric precedence, implicitly converts the other argument to that data type, and returns that data type.

因此,我們可以簡化重現情況:

SELECT TO_DATE('00:00') 
FROM DUAL 

,因爲你不提供一種格式,假設爲NLS_DATE_FORMAT,因此錯誤:'00'不是有效的一天。

(我真的不知道你想做什麼,但你可以嘗試使用純日期函數)。

+0

但是根據查詢中的表定義,start_time和end_time字段被聲明爲VARCHAR2。所以我不認爲是這樣。好主意,但。 – 2013-03-07 18:13:59

+0

對不起。我不知道列的類型,所以我只是猜測。 – 2013-03-08 08:12:18

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併發症得到同樣的結果。通常要比較日期,您應該使用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 
相關問題