【问题标题】:ORA-00932: inconsistent datatypes: expected CHAR got NUMBER while adding 1 to a dateORA-00932: 不一致的数据类型: 预期的 CHAR 在将 1 添加到日期时得到 NUMBER
【发布时间】:2015-06-30 11:44:51
【问题描述】:

可能是一个愚蠢的错误,但我自己无法弄清楚。当我在 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


    【解决方案1】:

    问题在于 DECODE 需要某种类型的 CHAR 参数,而 LAST_BD + 1 甚至 TO_DATE(LAST_BD... 分别返回一个 NUMBER 和一个 DATE。

    以下 SQL Fiddle 演示了如何解决此问题。

    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。

    【讨论】:

    • 但我需要日期,而不是日期序号
    • @SaagarEliasJacky 明白了,我只是在帮你理解错误而已。
    【解决方案2】:

    所以我没看错,您将LAST_BDVARCHAR2 转换为DATE(由于):

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

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

    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 只允许一种类型的值。

    【讨论】:

    • 谢谢...这行得通。只是提到它是to_char (to_date(LAST_BD, 'DD-MON-YYYY') - 1, 'DD-MON-YYYY'),而不是to_char (to_date(LAST_BD, 'DD-MON-YYYY') - 1), 'DD-MON-YYYY')
    【解决方案3】:

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

    【讨论】:

    • 这是简明扼要的解释和错误原因。基本上,您在第一个 THEN 部分之后提到的值的数据类型必须在同一级别的所有后续 THEN 中相同。感谢 user2038893 。拯救了我的一天。
    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2017-04-21
    • 2021-06-22
    • 2014-12-28
    相关资源
    最近更新 更多