Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如果非闰年为4月31日或2月29日,则在Oracle表中插入的日期是4月30日,而不是31日,2月28日,而不是29日_Sql_Database_Oracle - Fatal编程技术网

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

Sql 如果非闰年为4月31日或2月29日,则在Oracle表中插入的日期是4月30日,而不是31日,2月28日,而不是29日,sql,database,oracle,Sql,Database,Oracle,这是预期的行为吗?为什么 如果非闰年为4月31日或2月29日,则在Oracle表中插入的日期为4月30日,而不是2月31日;如果日期无效,则可能需要捕获错误 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 spe

这是预期的行为吗?为什么


如果非闰年为4月31日或2月29日,则在Oracle表中插入的日期为4月30日,而不是2月31日;如果日期无效,则可能需要捕获错误

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"
假设您在脚本下面运行。显然,由于日期无效,将引发错误

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;
/

嗯,如果我们这样做

select date '2018-02-29' from dual;
。。。或者这个

select date '2018-04-31' from dual;
。。。Oracle肯定会抛出
ORA-01847:月日必须介于1和月底之间

但我们这样做时,Oracle会处理一些事情:

select add_months(date '2018-01-29', 1) from dual; 
select add_months(date '2018-03-31', 1) from dual;
Oracle没有抛出错误,而是返回下个月的最后一天,分别是2018-02-28和2018-04-30。因此,它是有帮助的,并且抓住了一个愚蠢的错误,这个错误是由西历的怪癖引起的,这似乎足够公平(尽管你可能会选择不同意)。不过,它有一个,呃,有趣的副作用。这个

select add_months(date '2018-02-28', 1) from dual; 
。。。返回2018-03-31的

这是

正如@zirhc所指出的,INTERVAL的行为不同,这

select date '2018-01-29' + interval '1' month  from dual;

。。。将抛出预期的行为。

这不是我预期的行为。我希望抛出一个错误。为什么不向我们展示您正在执行的
insert
语句呢?我认为它应该抛出错误,而不是预期的行为。谢谢Dan@CodeHungry-当然,它应该抛出一个错误。因此,如果没有出现错误,则取决于insert语句的细节。因此,您需要发布实际的insert语句和一些重现问题的示例数据。或者不要,让我们猜你在做什么。
ORA-01830
此错误是由于将字符串
'31-APR-2018'
转换为日期而导致的格式错误,而不是因为该日期无效。如果您将
'31-MAY-2018'
转换为未使用显式掩码的日期,您应该会收到相同的错误,因为您的默认日期格式似乎不是
DD-MON-yyyyy
@APC,感谢您的更正,修改了我的答案。这只适用于添加月份,
到日期('31.01.2018'))+间隔“1”个月
返回ORA-01839:日期对于给定月份无效。只有添加月份才有此月末-workaround@zᴉ你说得很对。我试着猜测OP是如何获得他们在问题中描述的行为的。我也是:)我猜这只是他用来访问db的程序