Sql ORA-01843:条件更改时不是有效月份
我有以下错误的问题 ORA-01843:不是有效月份 如果我使用Sql ORA-01843:条件更改时不是有效月份,sql,oracle,Sql,Oracle,我有以下错误的问题 ORA-01843:不是有效月份 如果我使用 SELECT mx.work_order_no, mx.work_order_name, mx.comments FROM max_orders mx WHERE TO_DATE (wo_dt, 'dd/mm/rr') <= (TO_DATE (SYSDATE, 'dd/mon/rr') - 7) 我对你有意见 ORA-01843:不是有效月份 这是什么原因造成的?如何解决此错误 更新1 基本视图 SELECT
SELECT mx.work_order_no, mx.work_order_name, mx.comments
FROM max_orders mx
WHERE TO_DATE (wo_dt, 'dd/mm/rr') <= (TO_DATE (SYSDATE, 'dd/mon/rr') - 7)
我对你有意见
ORA-01843:不是有效月份
这是什么原因造成的?如何解决此错误
更新1
基本视图
SELECT work_order_no,
work_order_name,
wo_dt,
comments
FROM (SELECT mx_master.work_order_no,
mx_master.work_order_name,
SUBSTR (mx_master.uom, 1, 15) wo_dt,
mx_master.remarks
FROM mx_wo_data mx_master)
不要将
sysdate
转换为日期!只需使用:
WHERE TO_DATE(wo_dt, 'dd/mm/rr') >= trunc(SYSDATE - 7)
SYSDATE
已经是一个日期。您不应该将其传递到TO\u DATE()
。当您这样做的时候,您正在对字符串进行隐式转换,然后再进行显式转换。戈登·林诺夫已经展示了一种更好的方法
根据您添加的视图定义,wo_dt
是一个字符串。您希望它是dd/mm/rr
格式。错误告诉您该列中的值实际上不是该格式,因此您需要检查视图或基础表中的数据,以查看哪些记录的数据不正确
您可以使用排除格式不正确的值;或更有效地识别坏值,以便删除或更正它们,例如:
select * from max_orders
where my_to_date(wo_dt, 'dd/mm/rr') is null;
或从基础表:
select * from mx_wo_data
where my_to_date(substr(uom, 1, 8), 'dd/mm/rr') is null;
如果无法创建函数,则可以在匿名块中使用相同的逻辑
奇怪的是,更改条件会导致错误,因为您的(隐式和显式)转换是在计算条件之前应用的,使用函数意味着该列上的任何索引都不能使用;因此(在没有任何其他过滤器的情况下),您应该对两个查询进行完整的表扫描,在对列进行过滤之前,转换应该应用于列中的所有值,并且您应该以任何方式获得错误。因此,这并不能真正回答这个问题。我建议您创建一个存储函数来识别坏行:
create function invalid_date(p_d in varchar2) return number as
v_d date;
begin
v_d := TO_DATE(p_d, 'dd/mm/rr');
return 0;
exception
when others then
return 1;
end;
/
select * from mx_orders where invalid_date(wo_dt)=1;
由于条件
的原因,您可能会得到一个无效日期的值。不过,该条件是在日期转换之后应用的。看看执行计划会很有趣,看看条件的改变是否还在改变它;但我怀疑可能还有其他过滤器没有显示出来。不管怎样,wt_dt
都是一个字符串,其值与您的模式不匹配;或者它是一个日期,并且您的NLS设置与您正在使用的格式模型不匹配。数据可能有问题,是的-这就是为什么不应该将日期存储为字符串。TO_DATE(SYSDATE,'dd/mon/rr')
没有任何意义to_date()
将varchar
转换为date
<代码>系统日期已经是日期。To调用首先将sysdate
转换为varchar
,然后将其转换回date
。能否为表添加DDL以及两个查询的执行计划?您能否澄清第一个查询是否完全如图所示工作——您从两个查询中删除了其他条件以进行测试?好吧,我说桌子。。。max\u orders
是表还是视图?如果是视图,请显示其定义和基础表的结构。听起来仍然像是NLS问题……因此根据视图定义,wo_dt
是一个字符串,而不是一个日期,其中的值不代表所用格式模型的有效日期。我已经做了此更改,但是当我滚动结果或在报告中使用此查询时,在对报告页面进行分页时,我确实得到ORA-01843:不是有效的month错误。您是否怀疑数据有问题?因为这个查询或报告很久以来一直在工作,没有任何错误。谢谢,我尝试过使用WHERE wo_dt>=TRUNC(SYSDATE-7)
,这也会导致ORA-01843:不是有效的错误。max_orders
是一个视图,我在我的问题中把它的查询作为更新1。不,如果wo_dt
值为空(因此uom
为空),那么它就不会产生这个(或任何)错误。你有一个类似于08/19/14
的值,而不是19/08/14
@Polppan-你意识到我使用的是链接答案中Justin的my_to_date
函数,这与ammoQ的函数的想法相同,对吗?到目前为止不是正常的?也许这种联系太微妙了。ammoQ当然也能做到这一点。哎呀,我没有注意到你答案中的链接,否则我就不会发布类似的功能了:/Stumbious,这确实有助于找出错误的行,正如@Alex正确指出的,有几行是mm/dd/rr
格式的。谢谢。
create function invalid_date(p_d in varchar2) return number as
v_d date;
begin
v_d := TO_DATE(p_d, 'dd/mm/rr');
return 0;
exception
when others then
return 1;
end;
/
select * from mx_orders where invalid_date(wo_dt)=1;