Oracle日期格式之谜 - 为什么它不是可接受的格式?

时间:2015-06-29 15:37:17

标签: oracle date oracle11g

我对SQL很新,但仍然写了一些与我现在写的非常类似的查询。无论出于何种原因,当我运行此查询时,我返回'ORA-01821:日期格式无法识别'错误。我查看了这个并在Stack和其他地方环顾四周,我相信我的语法确实有意义所以我很困惑为什么我会抛出错误。

我的查询基于该月的哪一天运行。如果它是第一个,它应该运行在上个月的第15天。如果它是第16个,它应该在当月的1月15日运行。

这是我当月第一天的代码:

select 
case
   when to_char(sysdate, 'yyyymmdd') = to_char(sysdate, 'yyyymm' || '01') then (do a lot of things)
   .
   .
   .
end as FirstReportGroup
where *datetable* between between to_char(sysdate, 'yyyymm' || '16') and to_char(last_day(sysdate), 'yyyymmdd');

这是我16岁时的代码:

select 
case
   when to_char(sysdate, 'yyyymmdd') = to_char(sysdate, 'yyyymm' || '16') then (do a lot of things again)
   .
   .
   .
end as SecondReportGroup
where *datetable* between to_char(sysdate, 'yyyymm' || '01') and to_char(sysdate, 'yyyymm' || '15')

它一定是某种日期格式化语法错误​​,我只是没有看到。我真的很感激这里的帮助,我期待着解决这个问题!如果您需要更多信息,请告诉我。

感谢。

2 个答案:

答案 0 :(得分:1)

两个问题

  • 比较类似数据类型,因此两者上的日期或两者上的字符串,但不是日期和字符串
  • 两个to_char仅适用于某个日期,因此您需要to_char(sysdate, 'yyyymm') || '16'而不是to_char仅适用于该日期,您将在一个对to_char函数无效的字符串中进行仲裁。在功能之后这样做。

答案 1 :(得分:0)

通过使用case语句在where子句中生成开始/结束日期,您可能只需要进行一次查询即可。以下是案例陈述的一个例子:

with dts as (select sysdate dt from dual union all
             select to_date('02/06/2014 15:09:23', 'dd/mm/yyyy hh24:mi:ss') dt from dual)     
select dt,
       case when dt - trunc(dt, 'mm') < 16 then add_months(trunc(dt, 'mm'), -1) + 15 -- goes from 16th of previous month; change to 14 if needing from 15th.
            else trunc(dt, 'mm')
       end start_dt,
       case when dt - trunc(dt, 'mm') < 16 then trunc(dt, 'mm') -- goes from 16th of previous month; change to 14 if needing from 15th.
            else trunc(dt, 'mm') + 15
       end end_dt
from   dts;

DT                    START_DT              END_DT               
--------------------- --------------------- ---------------------
29/06/2015 12:50:00   01/06/2015 00:00:00   16/06/2015 00:00:00  
02/06/2014 15:09:23   16/05/2014 00:00:00   01/06/2014 00:00:00  

请记住a)Oracle中的DATE也有一个时间元素,b)你可能不希望在它们之间使用,因为这会使开始和结束时段包含在内(你可以在两个查询中出现行如果你得到end_date错误并且在end_date当天午夜后忘记任何事情,或者甚至可能完全错过行:相反,你可能想做类似的事情:

and datecol >= <case statement generating start_date>
and datecol < <case statement generating end_date>