尝试在 SQL 查询中输入 0 到 11 之间的月份时出现 oracle 错误 ORA-01843
Posted
技术标签:
【中文标题】尝试在 SQL 查询中输入 0 到 11 之间的月份时出现 oracle 错误 ORA-01843【英文标题】:oracle error ORA-01843 when trying to enter months between 0 to 11 in SQL Query 【发布时间】:2015-02-05 22:32:14 【问题描述】:我正在使用以下函数,它接受三个参数日期、要添加的年份和要添加的月份并返回最终日期。
create or replace function date_add_year_month(p_date in date, p_years in number, p_months in number)
return date
as
v_years number;
v_date date;
begin
v_date := add_months(p_date, p_months);
v_years := p_years + extract(year from v_date);
return to_date(v_years || (extract(month from v_date)) || (extract (day from v_date)), 'YYYYMMDD');
end;
/
现在如果我运行以下测试数据,我会收到无效月份的错误。
select date_add_year_month(date '2009-10-28', 0, 10) from dual;
select date_add_year_month(date '2009-10-28', 0, 11) from dual;
select date_add_year_month('2009-Jan-01', 5, 0) from dual;
select date_add_year_month(date '2009-Oct-28', -1, -5) from dual;
但是一旦我开始在函数中输入月份值 12 或以上,它就会开始给我一个输出。
select date_add_year_month(date '2009-10-28', 0, 12) from dual;
select date_add_year_month(date '2009-10-28', 0, 13) from dual;
select date_add_year_month(date '2009-Oct-28', 1, 26) from dual;
select date_add_year_month(date '2009-10-28', 0, 36) from dual;
select date_add_year_month(date '2009-10-28', -1, 26) from dual;
【问题讨论】:
【参考方案1】:当您执行extract (month from v_date)
时,结果是一个数字,可能是一个数字。将 10 个月添加到 2009-10-28 会得到 2010-08-28,从中提取月份数会得到 8 - 而不是 08
。在这种情况下,您将添加零年,因此您最终尝试这样做:
to_date(v_years || (extract(month from v_date)) || (extract (day from v_date)), 'YYYYMMDD')
变成:
to_date(2009 || 8 || 28), 'YYYYMMDD')
即隐式转换为字符串后:
to_date('2009828', 'YYYYMMDD')
... 82 不是有效的月份数。当您经过 11 个月时,您将得到 92。当您经过 12 个月时,虽然您回到 10 月,但提取得到 10,并且您回到字符串中正确数量的字符 - 匹配您的格式模型。 (如果你在 11 月通过了一个日期,那么 11 个月就可以了,因为它仍然会在 10 月结束,并且 extract 会给你 10,再次给你一个有效的月份。
所有其他日期和调整组合也发生了同样的事情。您也可以在日期编号方面遇到类似的问题。
您可以将提取的数字左填充为两个字符,但这样做会更简单:
return add_months(p_date, (p_years * 12) + p_months);
或者根本不使用您自己的函数,因为这样做并不比调用函数多多少。
【讨论】:
以上是关于尝试在 SQL 查询中输入 0 到 11 之间的月份时出现 oracle 错误 ORA-01843的主要内容,如果未能解决你的问题,请参考以下文章
如何在VB 中使用datediff计算某开始日期到结束日期之间的月数,并均分到每年