我想在oracle SQL developer中减去2个日期,inc_date存储为日期。我有以下代码:
select to_date(to_char(i_date,'yyyy-mm-dd'),'yyyy-mm-dd'),
to_date(to_char('2023-') || to_char(i_date,'mm-')|| to_char(i_date,'dd-'),'yyyy-mm-dd')
from data;
当我这样运行select时,我得到了我想要的结果,即使我减去了那2个,但即使没有减去,当我向下滚动结果时,大约250行的结果我突然得到错误消息“date not valid for month specified”.我理解错误消息,但我不明白为什么它给了我250个我想要的结果,然后错误弹出。
作为参考,我不能改变数据表本身的inc_date,我必须有2023年。简单地说,我想得到inc_date作为结果,其中每行都有2023年,但月份和日期保持不变。
3条答案
按热度按时间7jmck4yq1#
正如@ PonderStibons所指出的,这个错误表明你的数据中有一个闰日,例如2020-02-29。你的字符串操作会试图将其转换为2023-02-29,这不是一个有效的日期。
我不明白为什么它给了我250个我想要的结果,然后错误弹出。
结果以50个为一批(SQL Developer中的默认值;您可以在首选项中更改它)。日期和字符串操作是作为提取的一部分完成的,而不是在解析查询时完成的。有问题的日期出现在碰巧在第六批中提取的行中(此时-没有order-by子句,因此当您命中它时是不确定的)。前五个是OK的,并且对于这五个提取中的每一个,您都会获得50行,因此会看到250个结果。然后当它试图获取下一个50行时,它会遇到问题日期,这会生成错误。
有多种方法可以处理或跳过有问题的日期,同时仍然进行字符串操作,包括在Oracle的最新版本中使用the
to_date()
call中的default ... on conversion error
子句。具体执行什么取决于您希望如何处理闰日。另一种方法是避免字符串操作,而是进行本地日期操作。您可以使用
add_months
,并基于原始日期中的年份与2023年之间的差异乘以12:这将得到与大多数日期相同的结果,2020-02-29将转换为2020-02-28。
我在这里留下了
trunc()
来设置午夜的时间部分,正如@BarbarosÖzhan所说,你也可以在查询的第一部分使用它。当你把它们当作减法的日期时,你真的不需要截断它们,使用这种方法,因为时间是相同的,当你减法时,你仍然会得到整数天。
fiddle
减法的一个更基本的方法是将年差乘以365;但这不能解释闰年
w51jfk4q2#
简单一点:
样本数据:
查询:
fgw7neuy3#
我认为你必须处理i_date为NULL的情况。