例如以下SQL语句将会报错,因为相加后的日期为2018-09-31,但九月最多30天。
SELECT TO_DATE('2018-08-31', 'YYYY-MM-DD') + NUMTOYMINTERVAL(1, 'month') FROM SYS_DUMMY;
GS-00674, DATETIME with illegal month field
相似的情况还可能发生在闰年的年份,这里2016年是闰年,2月份有29天,当加上一年后,结果为2017年,但2017年不是闰年,其二月份最多28天,因此也会产生错误。
SELECT TO_DATE('2016-02-29', 'YYYY-MM-DD') + TO_YMINTERVAL('P1Y') FROM SYS_DUMMY;
GS-00674, DATETIME with illegal month field
其他例子
SELECT TO_DATE('2018-01-31', 'YYYY-MM-DD') + NUMTOYMINTERVAL(1, 'year') FROM SYS_DUMMY;
TO_DATE('2018-01-31', 'YYYY-MM-DD') + NUMTOYMINTERVAL(1, 'YEAR')
------------------------------------------------------------------
2019-01-31 00:00:00
1 rows fetched.
这里报错似乎对于用户来说不太友好,实质是我们对用户的期望不确定,加一个月的时间间隔,到底是下个月的当天还是说一个月为隐含的30天来相加。是由“一个月”这个定义本身的不确定性导致的(28/29/30/31)
一:
这里报错是内核做了加运算之后做了分段逻辑校验,从最小单位往最大单位校验。
各个版本的逻辑不一定相同,需要在版本中确定。
二:
Gauss中有处理加月的函数,可以解决我们遇到的问题;
如果函数中的天数是当月的最后一天,则返回值中的日期也为该月的最后一天。例如:
SELECT ADD_MONTHS(to_date('2016-02-29','yyyy-mm-dd'),1) from SYS_DUMMY;ADD_MONTHS(TO_DATE('2016-02-29','YYYY-MM-DD'),1)
------------------------------------------------
2016-03-31 00:00:00
1 rows fetched.