【问题标题】:ORA-01839: date not valid for month specifiedORA-01839: 日期对于指定月份无效
【发布时间】:2018-01-02 07:53:14
【问题描述】:

以下查询返回

select to_char( trunc(sysdate) - numtoyminterval(level - 1, 'month'), 'mon-yy') as month from dual connect by level <= 12

根据今天的日期(即 18 年 1 月 2 日)过去 12 个月。

如果今天的日期是 29-DEC-17,它会给出 oracle sql 错误: ORA-01839:指定月份的日期无效 (因为在减去结果中会有一个日期为 '29-FEB-17' 这是不可能的)。因此,在特定日期会弹出此错误。你建议如何克服这个问题?

【问题讨论】:

  • 你在这里真正想要什么输出?例如。 31号会出问题半年。应该显示哪一天?
  • 除了最简单的日期算术之外,最好使用预先设计的日期表。即使你有了这个,其中所讨论的日期周期是“参差不齐的”(有不同的天数),你必须包含逻辑来确定如何处理不包含特定日期的月份。例如,对于非闰年的 2 月 29 日,您是选择 2 月 28 日、3 月 1 日,还是完全忽略它?
  • @TimBiegeleisen 道歉蒂姆,我已经编辑了这个问题,以使要求更清楚,因为日期不需要显示在输出中,它可以采用“mon-yy”格式跨度>

标签: sql oracle


【解决方案1】:

我更喜欢 ADD_MONTHS(日期文字的 TRUNC 是愚蠢的,但我把它留给你,反正你会有 SYSDATE,不是吗?):

SQL> select to_char(add_months(trunc(date '2017-12-29'), -level), 'dd-mon-yy',
  2                 'nls_Date_language = english') as month
  3  from dual
  4  connect by level <= 12;

MONTH
------------------
29-nov-17
29-oct-17
29-sep-17
29-aug-17
29-jul-17
29-jun-17
29-may-17
29-apr-17
29-mar-17
28-feb-17
29-jan-17
29-dec-16

12 rows selected.

SQL>

【讨论】:

  • 这种方法的潜在问题是,2 月 28 日被选择用于一个月中最多 4 天(28、29、30、31)。现实世界中很少有这种行为是可取的。
  • 我不确定这是不是“问题”,这就是 Oracle 从日期中减去月份的方式。您能否更详细地解释您要解决的问题,以便有人可以提供更好的 解决方案?例如,如果“sysdate”是 12 月 31 日:您预计 2 月的哪一天?我的查询返回 2 月 28 日,并且 - 正如您所说的 wrong 结果,那么什么日期是正确的?
  • 我不是 OP - 我并不是说你的答案是错误的,我只是指出不能假设它是解决潜在问题的正确方法或要求(OP对此一无所知)。
  • 哈哈!我道歉,史蒂夫;没有足够注意谁说了什么。对不起。
  • 道歉@Littlefoot ,MONTH 列的格式应该是'mon-yy'
【解决方案2】:

INTERVAL YEAR TO MONTH 的这种行为已记录在案,请参阅Datetime/Interval Arithmetic

你应该考虑函数ADD_MONTHS

如果日期是该月的最后一天,或者如果生成的月份有 比日期的天分量少的天数,则结果是最后一个 结果月份的日期。否则结果同日 组件作为日期。

这取决于您的要求,您认为什么是“正确的”。事实上,“一个月”并没有固定的持续时间。

【讨论】:

  • 是的,这也很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多