to_date ora-01847每月的日期必须介于1和1月的最后一天之间

时间:2013-03-07 16:59:33

标签: sql oracle runtime-error

我正在尝试执行以下查询,但收到此错误:

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

查询是在两个不同的表中检查日期和时间的重叠

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

没有遇到任何错误。

2 个答案:

答案 0 :(得分:2)

重现错误:

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

ORA-01847:月中的某一天必须在1月到最后一天之间

NVL() description说:

  

参数expr1和expr2可以包含任何数据类型。如果他们的数据   类型不同,然后Oracle数据库隐式地将一个转换为   另一个。如果它们无法隐式转换,那么数据库   返回错误。隐式转换实现如下:

     
      
  • 如果expr1是字符数据,那么Oracle数据库会在比较它们之前将expr2转换为expr1的数据类型,并返回VARCHAR2 in   expr1的字符集。

  •   
  • 如果expr1是数字,那么Oracle数据库确定哪个参数具有最高的数字优先级,隐式转换另一个   该数据类型的参数,并返回该数据类型。

  •   

所以我们可以简化重现案例:

SELECT TO_DATE('00:00')
FROM DUAL

由于您没有提供格式,因此它假定NLS_DATE_FORMAT,因此错误:'00'不是有效日。

(我真的不知道你要做什么,但你可以尝试使用纯日期函数。)

答案 1 :(得分: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