ORA-00932:不一致的数据类型:预期CHAR在为日期添加1时获得NUMBER

问题描述 投票:3回答:3

可能是一个愚蠢的错误,但我自己无法弄清楚这一点。当我在Oracle 11g中运行此查询时。

如果在SO中回答了这个问题,请告诉我链接。

with LAST_BUSINESS_DAY as (select DECODE(to_char(last_day(to_date('29-mar-2013')), 'D'), 
                                  , '7', to_char((last_day('29-mar-2013') - 1), 'DD-MON-YYYY')
                                  , '1', to_char((last_day('29-mar-2013') - 2), 'DD-MON-YYYY')
                                  , to_char(last_day('29-apr-2013'), 'DD-MON-YYYY')) as LAST_BD from dual),
      HOLIDAYS as (select distinct rpt_day
                     from rpt_days rpt left join
                          calendars cal on rpt.calendar_id = cal.calendar_id
                    where rpt.type = 2 
                      and cal.group = 4)
  select case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
              then LAST_BD
              else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D')
                          , '6', LAST_BD
                          , '2', LAST_BD
                          , LAST_BD)
         end as LAST_BD_OF_MONTH
    from LAST_BUSINESS_DAY LBD 
         inner join HOLIDAYS H on LBD.LAST_BD = H.rpt_day

我得到了结果

LAST_BD_OF_MONTH
===================
29-MAR-2013

现在,当我尝试在LAST_BD日期添加一天时,它会抛出一个错误。

with LAST_BUSINESS_DAY as (select DECODE(to_char(last_day(to_date('29-mar-2013')), 'D'), 
                                  , '7', to_char((last_day('29-mar-2013') - 1), 'DD-MON-YYYY')
                                  , '1', to_char((last_day('29-mar-2013') - 2), 'DD-MON-YYYY')
                                  , to_char(last_day('29-apr-2013'), 'DD-MON-YYYY')) as LAST_BD from dual),
      HOLIDAYS as (select distinct rpt_day
                     from rpt_days rpt left join
                          calendars cal on rpt.calendar_id = cal.calendar_id
                    where rpt.type = 2 
                      and cal.group = 4)
  select case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
              then LAST_BD
              else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D') -- line 35
                          , '6', LAST_BD - 1 -- CHANGED THIS
                          , '2', LAST_BD + 1 -- CHANGED THIS
                          , LAST_BD)
         end as LAST_BD_OF_MONTH
    from LAST_BUSINESS_DAY LBD 
         inner join HOLIDAYS H on LBD.LAST_BD = H.rpt_day

错误信息

ORA-00932:不一致的数据类型:预期CHAR得到NUMBER 00932. 00000 - “不一致的数据类型:预期%s得到%s”*原因: *动作:行错误:35列:20

正如我所说,这可能是我身边的一个简单的忽视。我尝试将LAST_BD转换为date,但没有奏效。

我尝试更改DECODE如下

case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
     then LAST_BD
     else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D')
                 , '6', to_date(LAST_BD, 'DD-MON-YYYY') - 1
                 , '2', LAST_BD + 1 -- line 37
                 , LAST_BD)
end as LAST_BD_OF_MONTH

并得到此错误:

ORA-00932:不一致的数据类型:预期DATE得到NUMBER 00932. 00000 - “不一致的数据类型:预期%s得到%s”*原因: *动作:行错误:37列:42

所以,我把line 37改成了这个,

case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
     then LAST_BD
     else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D')
                , '6', to_date(LAST_BD, 'DD-MON-YYYY') - 1
                , '2', to_date(LAST_BD, 'DD-MON-YYYY') + 1
                , LAST_BD)
end as LAST_BD_OF_MONTH

而这次是一个不同的信息。

ORA-00932:不一致的数据类型:预期CHAR得到DATE 00932. 00000 - “不一致的数据类型:预期%s得到%s”*原因: *动作:行错误:35列:20

非常感谢任何帮助以纠正这一点。

答案:

with LAST_BUSINESS_DAY as (select DECODE(to_char(last_day(to_date('29-mar-2013')), 'D'), 
                                  , '7', to_char((last_day('29-mar-2013') - 1), 'DD-MON-YYYY')
                                  , '1', to_char((last_day('29-mar-2013') - 2), 'DD-MON-YYYY')
                                  , to_char(last_day('29-apr-2013'), 'DD-MON-YYYY')) as LAST_BD from dual),
      HOLIDAYS as (select distinct rpt_day
                     from rpt_days rpt left join
                          calendars cal on rpt.calendar_id = cal.calendar_id
                    where rpt.type = 2 
                      and cal.group = 4)
  select case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
              then LAST_BD
              else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D')
                          , '6', to_char (to_date(LAST_BD, 'DD-MON-YYYY') - 1, 'DD-MON-YYYY')
                          , '2', to_char (to_date(LAST_BD, 'DD-MON-YYYY') + 1, 'DD-MON-YYYY')
                          , LAST_BD)
         end as LAST_BD_OF_MONTH
    from LAST_BUSINESS_DAY LBD 
         inner join HOLIDAYS H on LBD.LAST_BD = H.rpt_day
sql oracle oracle11g
3个回答
3
投票

所以我认为是正确的,你将LAST_BDfrom VARCHAR2转换为DATE(由于):

to_date(LAST_BD, 'DD-MON-YYYY') 

在第二个查询中,您尝试从此1中减去VARCHAR2

LAST_BD - 1

这不行。结果你得到错误:

ORA-00932: inconsistent datatypes: expected CHAR got NUMBER

可能有用的是,如果你将它转换为DATE,添加1并将其转换回VARCHAR2

with LAST_BUSINESS_DAY as (select DECODE(to_char(last_day(to_date('29-mar-2013')), 'D'), 
                                  , '7', to_char((last_day('29-mar-2013') - 1), 'DD-MON-YYYY')
                                  , '1', to_char((last_day('29-mar-2013') - 2), 'DD-MON-YYYY')
                                  , to_char(last_day('29-apr-2013'), 'DD-MON-YYYY')) as LAST_BD from dual),
      HOLIDAYS as (select distinct rpt_day
                     from rpt_days rpt left join
                          calendars cal on rpt.calendar_id = cal.calendar_id
                    where rpt.type = 2 
                      and cal.group = 4)
  select case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
              then LAST_BD
              else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D') -- line 35
                     , '6', to_char (to_date(LAST_BD, 'DD-MON-YYYY') - 1, 'DD-MON-YYYY') 
                     , '2', to_char (to_date(LAST_BD, 'DD-MON-YYYY') + 1, 'DD-MON-YYYY') 
                          , LAST_BD)
         end as LAST_BD_OF_MONTH
    from LAST_BUSINESS_DAY LBD 
         inner join HOLIDAYS H on LBD.LAST_BD = H.rpt_day

请注意,需要转换回VARCHAR2,因为DECODE只允许一种类型的值。


2
投票

问题是DECODE期望某种CHAR参数和LAST_BD + 1甚至TO_DATE(LAST_BD...分别返回NUMBER和DATE。

以下SQL小提琴演示如何解决此问题。

http://sqlfiddle.com/#!4/8ac4a3/9

这是查询:

with LAST_BUSINESS_DAY as (select DECODE(to_char(last_day(to_date('29-mar-2013')), 'D')
                                  , '7', to_char((last_day('29-mar-2013') - 1), 'DD-MON-YYYY')
                                  , '1', to_char((last_day('29-mar-2013') - 2), 'DD-MON-YYYY')
                                  , to_char(last_day('29-apr-2013'), 'DD-MON-YYYY')) as LAST_BD from dual),
      HOLIDAYS as (select distinct reporting_day
                     from tbm_reporting_days trdy left join
                          tbm_calendars tcal on trdy.calendar_id = tcal.calendar_id
                    where trdy.type = 2 
                      and tcal.site_id = 4)
  select case when to_char(to_date(LAST_BD, 'DD-MON-YYYY'), 'D') is null
              then LAST_BD
              else DECODE(to_char(to_date(LAST_BD, 'DD-MON-YYYY') , 'D')
                          , '6', TO_CHAR(
                              (TO_DATE(LAST_BD, 'DD-MON-YYYY') - 1), 'D')
                          , '2', TO_CHAR(
                              (TO_DATE(LAST_BD, 'DD-MON-YYYY') - 1), 'D')
                          , LAST_BD)
         end as LAST_BD_OF_MONTH
    from LAST_BUSINESS_DAY LBD 
         inner join HOLIDAYS H on LBD.LAST_BD = H.reporting_day

您必须使用TO_CHAR将数字或日期转换回CHAR。


0
投票

似乎Oracle要求case结构所有then表达式的类型与第一个表达式之后的表达式类型一致。 不执行任何类型转换。

© www.soinside.com 2019 - 2024. All rights reserved.