经过深入研究,很清楚为什么我们的某些选择在今天不起作用。该错误是由关键字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;