文章目录
- 1. 前言
- 2. 先说结论
- 3. 案例演示
1. 前言
- 最近在对某些表进行旧数据的删除,必然是通过【时间】删除之前较为久远的数据,比如1年前,6个月前,7天前的数据等等情况,这个时候的SQL,必然会出现条件:
where time < 时间 - 间隔
- 对于oralce来说,当时使用了
where time < SYSDATE - INTERVAL '10' MONTH
,一开始自测也好好的,过了几天之后,则报错:ORA-01839:指定月份的日期无效 - 因此写这篇文章记录一下该事件。
2. 先说结论
- 导致会报错ORA-01839:指定月份的日期无效的原因如下:
- 若此时日期是:
2023-05-31
,使用SQL- INTERVAL '3' MONTH
,则会得到2023-02-31
,2月份不可能会有31号 - 因此会报错指定月份的日期无效,该报错不是说
- INTERVAL '3' MONTH
中的3有问题,而是指得到的结果日期有问题 - INTERVAL 不会特殊处理 2月份的情况,因此是有一定缺陷的。
- 若此时日期是:
- 解决方法:使用oracle中的
ADD_MONTHS
函数,其是会自动调整日期:- 使用方式:ADD_MONTHS(日期,正负数字),如:ADD_MONTHS(日期,3) 是向后加三个月,ADD_MONTHS(日期,-3) 是向前减三个月
- 若此时日期是:
2023-05-31
,使用SQLADD_MONTHS('2023-05-31',-3)
,则会得到2023-02-28
,不会报错,是函数自带处理。
3. 案例演示
-
使用oracle的学习网站,介绍使用点这里
-
第一种,使用INTERVAL对日期进行相减:
SELECT TO_DATE('2023-5-30 00:00:00','YYYY-MM-DD HH24:MI:ss') - INTERVAL '3' MONTH FROM DUAL;
-
当时想法是,如果减月份会有2月份特殊的情况,那么改成减天数,是否则正常了呢?
SELECT TO_DATE('2023-5-30 00:00:00','YYYY-MM-DD HH24:MI:ss') - INTERVAL '91' DAY FROM DUAL;
如下图:
- 但是细心的人会发现:这里的SQL,减的是91天,而不是90天,因为减天数,需要考虑到大小月份的问题,如果需求是前几个月的数据删除掉,使用天数来,这方面的考虑是必不可少的,因此得不偿失。
- 再加上使用天数来相加减,还有另一个致命的问题,它无法减超过100的天数,负责会报错:
-
因此采用另一种方式,使用oracle自带的ADD_MONTHS函数:
SELECT ADD_MONTHS(to_date('2023-5-31 00:00:00','YYYY-MM-DD HH24:MI:ss'),-3) FROM DUAL;