我们都知道今天是特别的一天。它是闰年的29th of February 2016
。
我们收到Oracle DB中某些表的错误消息。错误是:Oracle ORA-01839: date not valid for month specified
。
例如,发生错误的简单选择:select * from table where table_date > sysdate -0.1;
对于其他表,这个选择没有问题,只是对于某些表。
有没有办法解决这个问题?因为我们今天无法使用很多桌子。
我们正在使用Oracle 12c
。
答案 0 :(得分:8)
经过深入研究,明确了为什么我们的一些选择今天不起作用。该错误是由关键字interval
及其已知问题引起的。 (或者ANSI/ISO spec说它应该如何工作,第205页底部/第206页上方)
以下是来自oracle community blog:
的qoute问题:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '2' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '3' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '4' year as dt from dual;
29-FEB-16 00:00:00
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' day as dt from dual;
01-MAR-12 00:00:00
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' month as dt from dual;
29-MAR-12 00:00:00
<强>答案强>:
这就是INTERVAL的工作方式。闰年是最少的 问题;将1个月添加到3月31日会导致相同的错误。如果你 想确保结果是有效的DATE,然后使用 ADD_MONTHS。 (添加年份没有单独的功能;使用 ADD_MONTH(SYSDATE,12 * n)获取从现在起n年的DATE。)
为什么会出现这种情况:
在我们的例子中,出于安全原因,我们在某些表中使用了虚拟专用数据库。我们在大多数选择中应用了interval
关键字。
该怎么做:
改为使用ADD_MONTHS
。
select add_months(to_date('2012-feb-29','yyyy-mon-dd'), 12) as dt from dual;