Oracle DB Ora-01839:指定月份的日期无效。 29-02-2016 闰年

Oracle DB Ora-01839: date not valid for month specified. 29-02-2016 leap year

我们都知道今天是个特别的日子。它是 闰年 29th of February 2016

我们从 Oracle 数据库中的某些表收到错误消息。错误是:Oracle ORA-01839: date not valid for month specified.

例如发生错误的简单select:select * from table where table_date > sysdate -0.1;

对于其他表,这个 select 没有问题,只是对于某些表。

有办法解决这个问题吗?因为我们今天不能使用很多表。

我们正在使用 Oracle 12c

经过深入研究,很清楚为什么我们的一些选择今天不起作用。该错误是由关键字 interval 引起的,这是一个已知问题。 (或者 ANSI/ISO spec 说它应该如何工作,第 205 页底部/第 206 页顶部)

这是来自 oracle community blog 的引述:

问题

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

回答:

That's just how INTERVALs work. Leap years are the least of the problem; adding 1 month to March 31 results in the same error. If you want to make sure that the result is a valid DATE, then use ADD_MONTHS. (There's no separate function for adding years; use ADD_MONTH (SYSDATE, 12*n) to get the DATE that is n years from now.)


为什么会发生在我们的案例中:

在我们的案例中,出于安全原因,我们对某些表使用了虚拟专用数据库。我们在大多数选择中应用了 interval 关键字。

改为做什么:

改用ADD_MONTHS

select add_months(to_date('2012-feb-29','yyyy-mon-dd'), 12) as dt from dual;