ORA-01843:无效月份何时更改条件

时间:2014-08-19 11:05:00

标签: 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)

但是,如果我将where where子句更改为

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)

3 个答案:

答案 0 :(得分:3)

SYSDATE已经是约会了。你不应该将它传递给TO_DATE()。当你这样做时,你正在进行一个字符串的隐式转换,以及一个显式的转换。 Gordon Linoff已经展示了更好的方法。

根据您添加的视图定义,wo_dt是一个字符串。您希望它采用dd/mm/rr格式。该错误告诉您该列中有哪些值实际上不是该格式,因此您需要检查视图或基础表中的数据,以查看哪些记录的数据不正确。

您可以使用something like this排除不正确格式的值;或更有用地识别坏值,以便可以删除或纠正它们,例如,有类似的东西:

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;

如果无法创建函数,则可以在匿名块中使用相同的逻辑。


奇怪的是,更改条件会导致错误,因为在计算条件之前应用了(隐式和显式)转换,并且使用函数意味着不能使用该列上的任何索引;因此(在没有任何其他过滤器的情况下)您应该对两个查询执行全表扫描,转换应该在过滤之前应用于列中的所有值,并且您应该以任何方式获得错误。所以这并没有真正回答问题的这一方面。

答案 1 :(得分:2)

请勿将sysdate转换为日期!只需使用:

WHERE TO_DATE(wo_dt, 'dd/mm/rr') >= trunc(SYSDATE - 7)

答案 2 :(得分:2)

我建议你创建一个存储函数来识别坏行:

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;