在4月31日或2月29日的非闰年,在Oracle表中插入的日期是4月30日而不是2月31日和28日而不是29日

时间:2018-04-24 02:04:21

标签: sql database oracle

预计会出现这种情况吗?为什么?

4月31日或2月29日非闰年,在Oracle表中插入的日期是4月30日,而不是2月31日和28日,而不是2月29日。

2 个答案:

答案 0 :(得分:0)

如果日期无效,也许您想要捕获错误。

让我们说你跑到脚本下面。显然,由于日期无效,将引发错误。

ALTER SESSION SET NLS_DATE_FORMAT='MM/DD/YYYY';

DECLARE
    v_date DATE;
BEGIN
    v_date := '04/31/2018'';
END;
/

Error report -
ORA-01839: date not valid for month specified
ORA-06512: at line 4
01839. 00000 -  "date not valid for month specified"

如果要捕获错误,可以通过定义异常来完成。

DECLARE
    v_date DATE;
    ORA_1839 EXCEPTION;
    PRAGMA EXCEPTION_INIT(ORA_1839, -1839);
BEGIN
    v_date := '04/31/2018';
EXCEPTION
    WHEN ORA_1839 THEN
        DBMS_OUTPUT.PUT_LINE('ERROR 1839 HAD CAUGHT');
END;
/

答案 1 :(得分:0)

嗯,如果我们这样做......

select date '2018-04-31' from dual;

......或者......

ORA-01847: day of month must be between 1 and last day of month

......甲骨文肯定会向select add_months(date '2018-01-29', 1) from dual; select add_months(date '2018-03-31', 1) from dual; 投掷。

但是当我们这样做时,Oracle处理事情:

2018-02-28

Oracle不会抛出错误,而是分别返回下个月的最后一天2018-04-30select add_months(date '2018-02-28', 1) from dual; 。因此,它有助于捕捉西方日历怪癖造成的愚蠢错误,这似乎很公平(尽管你可能会选择不同意)。但是,它有一个,呃,有趣的副作用。这......

2018-03-31

...返回select date '2018-01-29' + interval '1' month from dual; ,因为月的最后一天,这可能并不总是预期或期望。

这是a SQLFiddle to play with

正如@zirhc指出的那样,INTERVAL表现得与众不同,而这......

jobs

...将投掷预期的ORA-01839: date not valid for month specified