6

我们都知道今天是一个特殊的日子。它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.

4

1 回答 1

12

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

这是来自oracle 社区博客的引用:

问题

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;
于 2016-02-29T10:14:51.140 回答