0

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

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

没有遇到错误。

4

2 回答 2

2

要重现错误:

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

ORA-01847: 月中的某天必须介于 1 和月的最后一天之间

NVL() 描述说:

参数 expr1 和 expr2 可以具有任何数据类型。如果它们的数据类型不同,那么 Oracle 数据库会隐式地将一种转换为另一种。如果它们不能被隐式转换,那么数据库会返回一个错误。隐式转换实现如下:

  • 如果 expr1 是字符数据,则 Oracle 数据库将 expr2 转换为 expr1 的数据类型,然后再进行比较,并以 expr1 的字符集返回 VARCHAR2。

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

所以我们可以简化重现情况:

SELECT TO_DATE('00:00')
FROM DUAL

由于您没有提供格式,因此假设NLS_DATE_FORMAT为 ,因此错误:'00' is not a valid day。

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

于 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 回答