2016-11-25 90 views
0

我在这个查询问题的日期:ORA-01847错误得到

select to_char(ADD_MONTHS((LAST_DAY(to_date(DATEVAR, 'yyyymmdd'))+1),-1),'yyyymmdd') from mytable 
where ROWNUM=1 
and var = to_char(last_day(to_date(DATEVAR, 'yyyyMMdd')), 'WW')-1; 

我希望它返回时,VAR是本月的最后一周数量和返回空值时,它不是“T如果我的变种是 '29'(weekNumber)我得到:

ORA-01847: “一个月的天必须在1月的最后一天之间”

但是,如果我改变周数为'30'(本月的上周数)我得到正确的结果:

'20160701' 

请帮助谢谢。

+0

上周数量?上个星期的月数是30?当你的思想混淆在“星期”和“日”之间时,你如何期望写出正确的代码?没有办法从困惑的想法中编写正确的代码。不管其他什么,你的最后一行将会失败:你计算一个'to_char()'的东西(无所谓),然后你从结果字符串中减1。你需要一种不同的方法来问你的问题:陈述你正在做什么,你的数据是什么样的,你想要什么输出 - 不要只显示你的代码(反正它不能正常工作)。 – mathguy

+0

@mathguy,但今年有超过30周,那么为什么你会认为OP在日期和星期数字之间变得混乱? – Boneist

+2

***从不***,*永远*在'date'值上调用'to_date()'。 –

回答

0

我没有看到您的代码有问题? var设置为30时:

WITH mytable AS (SELECT trunc(SYSDATE, 'yyyy') - 1 + LEVEL datevar 
       FROM dual 
       CONNECT BY LEVEL <= 366) 
SELECT to_char(add_months((last_day(datevar) + 1), -1), 'yyyymmdd') ret_col 
FROM mytable 
WHERE rownum = 1 
AND 30 = to_number(to_char(last_day(datevar), 'WW'))- 1; 

RET_COL 
-------- 
20160701 

在上面的查询中将30更改为29,并且没有返回行。

我唯一能想到的就是你的datevar列有一个VARCHAR2而不是DATE的数据类型,并且由于你的NLS_DATE_FORMAT设置你遇到了一些隐含的日期转换问题。

N.B.编辑我的查询以删除datevar上的to_date(),(因为我将datevars定义为DATEs,这是一件非常愚蠢的事情!谢谢@mathguy。)另外,添加一个明确的to_number ()在where子句中。

+1

是的我的数据类型是VARCHAR2,我会改变为DATE,thx –

+0

您仍然依赖于我在OP的评论中指出的同样的隐式转换 - 在最后一行中,您将从字符串中减去1 。这可能是Oracle猜测正确的情况之一,但从字符串中减1通常不是一个好习惯。 – mathguy

+0

@mathguy在这个例子中,将字符串隐式转换为数字是相当安全的。但我明白你的意思,并且增加了一个明确的to_number() – Boneist