【问题标题】:Oracle error: ORA-01839: date not valid for month specifiedOracle 错误:ORA-01839:指定月份的日期无效
【发布时间】:2014-09-16 14:19:59
【问题描述】:

好的,伙计们,首先,我已经检查了许多有关此错误的网站,但不幸的是,它们都没有帮助我。我有以下简单的查询:

select * from (   
       select to_date(cal.year || cal.month || cal.day, 'yyyymmdd') as datew, 
              cal.daytype as type
       from vw_calendar cal)
where datew > sysdate;

当我尝试执行整个查询时,会出现此错误:

ORA-01839: 指定月份的日期无效

如果我只执行查询:

select to_date(cal.year || cal.month || cal.day, 'yyyymmdd') as datew, 
       cal.daytype as type
from vw_calendar cal;

它工作得非常好。如果要查看查询结果:http://pastebin.com/PV95g3ac

我检查了一个月中的日子,比如第 31 天或闰年,一切似乎都是正确的。我不知道该怎么办了。我的数据库是 Oracle 10g,我尝试在 SQL Developer 和 PL/SQL Developer 上执行查询。两个 IDE 上的相同错误。

【问题讨论】:

  • vw_calendar 中有多少行?您的 pastebin 缺少 6 个日期:2014-03-05、2014-06-12、2014-06-17、2014-06-23、2014-07-04 和 2014-07-08。如果您认为应该有所有日期,那么也许可以弄清楚为什么没有显示这六个 - 我怀疑存在无效值。您的客户似乎原谅了更简单的查询,但可能隐藏了错误(?)。如果它是一个视图,您可以显示它的定义吗?你能显示数据类型吗?
  • 共有 4377 行(我使用了select count(*) from vw_calendar)。我没有注意到这些日期丢失了,我会调查一下,但我想丢失与我的问题无关。无论如何,我已经制作了另一个带有 2014 年 6 月日期的粘贴箱:pastebin.com/imKQTHwP。关于数据类型,对我来说很难,因为这个视图只是来自 ERP(JDE Edwards Enterprise One)的另一个视图的包装。
  • 你可以describe vw_calendar。从新的 pastebin 来看,它们似乎是 varchar2 字段,但确认它和长度可能有用。尽管我仍然想不出任何可以让一个查询运行但不能让另一个查询运行的方法;除了一些东西被推到视图中,但它不像 sysdate 可以自动分解为年/月/日。您是否尝试过按年过滤内部查询以查看是否可以缩小问题范围?
  • 感谢您提供有关describe 的有用提示。这里是数据类型:pastebin.com/fndMJX8K。我用where cal.year = 2014where cal.year = 2014 and cal.month = 06; 尝试了内部查询,效果很好。我尝试了其他年份,例如 2012 年和 2013 年。一切都在运行。但是,如果我从查询中删除 where dataw > sysdate,它也可以工作。

标签: sql oracle oracle10g


【解决方案1】:

实际上,问题是有些月份有 30 天,有些月份有 31 天,所以您正在形成的查询,它试图获取该月的第 31 天,这是无效的,因此出现错误。例如:

它可能会尝试像这样的日期:2016 年 11 月 31 日,这是不正确的,11 月只有 30 天。

【讨论】:

    【解决方案2】:

    好吧,我找到了一个解决方法,而不是解决方案。如果有人知道此问题的“正确”解决方案,如果您与我们分享,我将不胜感激。我的“解决方案”将日期转换为数字,然后与sysdate(也转换)进行比较。看看:

    select * from 
           ( select to_number(cal.year||cal.month||cal.day) as datew, 
                    cal.daytype as type from vw_calendar cal ) a 
    where a.datew > to_number(to_char(sysdate, 'yyyymmdd'));
    

    谢谢大家!

    【讨论】:

      【解决方案3】:

      为内部查询使用别名

      select * from (   
             select to_date(cal.year || cal.month || cal.day, 'yyyymmdd') as datew, 
                    cal.daytype as type
             from vw_calendar cal) a
      where a.datew > sysdate;
      

      【讨论】:

      • 虽然为嵌套查询使用别名当然是一种好习惯,但这与原始问题有什么关系?
      • 抱歉,发生了同样的错误。我尝试更改删除 sysdate 并放入 to_date() 的“where 部分”。但没有成功。我的代码:where mycal.data > to_date('20140101', 'yyyymmdd');
      • @RicardoGiaviti select * from (select to_date(cal.year||cal.month||cal.day,'yyyymmdd') as datew,cal.daytype as type from vw_calendar cal) a where trunc (a.datew) > trunc(sysdate);
      • @VigneshKumaresan 同样的错误。这个错误把我吓坏了。我正在考虑在 Oracle 上开票。
      • 里卡多,我也遇到了同样的事情。
      猜你喜欢
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 2021-11-06
      • 2015-11-07
      • 1970-01-01
      相关资源
      最近更新 更多