- 2.28日,客戶微信公眾號(hào)更新賬單列表功能:業(yè)主群里反饋用戶查到的賬單記錄不是自己的,經(jīng)驗(yàn)證和推測(cè)是同事寫(xiě)死了用戶編號(hào)。好吧?。。≡诩肄k公,有點(diǎn)馬虎,表示理解吧。
- 2.29日,星期六,懶覺(jué)還沒(méi)睡醒,業(yè)主群里反饋賬單查不到了。I'm Angry,直接把問(wèn)題截圖轉(zhuǎn)發(fā)到了小組溝通群里。
轉(zhuǎn)過(guò)頭來(lái)一想,不對(duì)呀,昨天更新后是可以正常使用的呀。這家伙也不會(huì)這么用工,加班又給更新一版。感覺(jué)不對(duì),查日志。
賬單列表是默認(rèn)加載近一年的,也沒(méi)有傳遞時(shí)間相關(guān)的信息呀,怎么就指定的月份日期無(wú)效呢。直接在后臺(tái)執(zhí)行對(duì)應(yīng)SQL,還是報(bào)錯(cuò)。
ORA-01839: 指定月份的日期無(wú)效
01839. 00000 - "date not valid for month specified"
看來(lái)是SQL語(yǔ)句的問(wèn)題,但是接口最近就沒(méi)有更新呀。最終鎖定在
sysdate - interval '1' YEAR
--當(dāng)然這個(gè)問(wèn)題必須是在特定日期才會(huì)出現(xiàn)的,比如
select TO_DATE('2020-02-29','yyyy-MM-dd') - interval '1' YEAR from dual
經(jīng)網(wǎng)上查詢,原來(lái)這個(gè)問(wèn)題是因?yàn)殚c年29號(hào)以及oracel的interval處理機(jī)制造成。
Query containing SYSDATE - INTERVAL '1' YEAR fails for today's date(29th February 2016)
這里先說(shuō)替代寫(xiě)法:
select add_months(TO_DATE('2020-02-29','yyyy-MM-dd'),-12) from dual
這里有問(wèn)題的說(shuō)明:
It might be disappointing, but it is to be expected. [It is mentioned in the documentation](https://docs.oracle.com/database/121/SQLRF/sql_elements001.htm#i48042):
When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error. For example, the next two statements return errors:
SELECT TO_DATE('31-AUG-2004','DD-MON-YYYY') + TO_YMINTERVAL('0-1') FROM DUAL;
SELECT TO_DATE('29-FEB-2004','DD-MON-YYYY') + TO_YMINTERVAL('1-0') FROM DUAL;
The first fails because adding one month to a 31-day month would result in September 31, which is not a valid date. The second fails because adding one year to a date that exists only every four years is not valid.
大概意思是:
Oracle的官方文檔中已經(jīng)說(shuō)了:interval計(jì)算返回一個(gè)datetime值,返回值必須是一個(gè)準(zhǔn)確的datetime值,否則返回錯(cuò)誤。
說(shuō)白了,interval計(jì)算后,Oracle不會(huì)做轉(zhuǎn)換,比如第一種情況,沒(méi)有31號(hào),不會(huì)幫你轉(zhuǎn)到次月1號(hào);第二種情況,沒(méi)有29號(hào),不會(huì)幫你轉(zhuǎn)到次月1號(hào)或本月20號(hào)。因?yàn)檫@樣不準(zhǔn)確。
最后感嘆一下,自己遇到了破解了一個(gè)4年一遇的bug?。?!
|