to_date ora-01847 月份中的某天必须介于 1 和该月的最后一天之间
Posted
技术标签:
【中文标题】to_date ora-01847 月份中的某天必须介于 1 和该月的最后一天之间【英文标题】:to_date ora-01847 day of month must be between 1 and last day of month 【发布时间】:2013-03-07 16:59:32 【问题描述】:我正在尝试执行以下查询,但收到此错误:
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
没有遇到错误。
【问题讨论】:
四个日期字段之一是否有可能具有NULL
值?
尝试用 NULL 代替 start_date1
的测试查询:我敢打赌它会给出同样的错误。
日期字段是必填字段...所以所有表格都没有空日期字段
然后尝试针对所有涉及的字段和表运行测试查询的变体。分享和享受。
【参考方案1】:
重现错误:
SELECT NVL(SYSDATE,'00:00')
FROM DUAL
ORA-01847: 日期必须介于 1 和最后一天之间
NVL() description 说:
参数 expr1 和 expr2 可以具有任何数据类型。如果他们的数据 类型不同,则 Oracle 数据库隐式转换为 另一个。如果它们不能被隐式转换,那么数据库 返回错误。隐式转换实现如下:
如果 expr1 是字符数据,那么 Oracle 数据库在比较它们之前将 expr2 转换为 expr1 的数据类型,并在 expr1 的字符集。
如果 expr1 是数字,则 Oracle 数据库确定哪个参数具有最高的数字优先级,隐式转换另一个 该数据类型的参数,并返回该数据类型。
所以我们可以简化重现情况:
SELECT TO_DATE('00:00')
FROM DUAL
由于您没有提供格式,因此假设为 NLS_DATE_FORMAT
,因此错误:'00' is not a valid day。
(我真的不知道您要做什么,但您可以尝试使用纯日期函数。)
【讨论】:
但是根据查询中的表定义,start_time 和 end_time 字段被声明为 VARCHAR2。因此,我认为不是这样。好主意,不过。 那么对不起。我不知道列类型,所以我只是猜测。【参考方案2】:您的格式需要修正。这是您的初始设置:
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
【讨论】:
以上是关于to_date ora-01847 月份中的某天必须介于 1 和该月的最后一天之间的主要内容,如果未能解决你的问题,请参考以下文章