【问题标题】:ORA-00905: missing keyword in case statementORA-00905: case 语句中缺少关键字
【发布时间】:2020-08-14 01:12:09
【问题描述】:

我收到 ORA-00905:在我的 when 子句中的 case 语句中缺少关键字。以下是查询。

  vsqlstr := 'select name, enrollement_dt,case_name, dept, subject, city, state, zip from enrollement where ';
    vsqlstr :=vsqlstr ||' 
    AND CASE
        WHEN TO_CHAR(SYSDATE,''MM'') <= ''06'' THEN enrollement_dt <= to_date(''12''||(EXTRACT(YEAR FROM SYSDATE)-1), ''MMYYYY'') 
        ELSE enrollement_dt >= to_date(''07''||(EXTRACT(YEAR FROM SYSDATE)), ''MMYYYY'') 
    END ';

【问题讨论】:

    标签: java sql oracle oracle11g


    【解决方案1】:

    您不能在 oracle 的查询中将布尔值作为可选内容,您只能在例如WHERE/ON 子句等

    即这是无效的:

    select case when 1=1 then 2>3 else 4>5 end from dual
                              ^^^
        can't have something that evaluates to a boolean type here
    

    这是有效的:

    select case when 1=1 then 'TRUE' else 'FALSE' end from dual
    

    您可以稍后将这些值与某些东西进行比较以实现布尔值:

    WHERE CASE WHEN x=y THEN 'T' ELSE 'F' END = 'T'
    

    但是你不能单独使用布尔值。这也是无效的:

    WHERE CASE WHEN x=y THEN 1=1 ELSE 1=0 END
    

    在您的情况下,将案例试图实现的布尔值提升到 WHERE 谓词中:

    WHERE (
     /*CASE 
         WHEN*/ TO_CHAR(SYSDATE,''MM'') <= ''06'' /*THEN*/ AND enrollement_dt <= to_date(''12''||(EXTRACT(YEAR FROM SYSDATE)-1), ''MMYYYY'')
      ) OR 
        /*ELSE*/ enrollement_dt >= to_date(''07''||(EXTRACT(YEAR FROM SYSDATE)), ''MMYYYY'') 
    /*END*/
    

    (我在作为 cmets 时留下了案例,以向您展示已编辑的内容)

    【讨论】:

      【解决方案2】:

      评论太长了。

      您使用的是case 表达式,而不是case 语句。这不仅仅是更糟的区别。 SQL 中的表达式(通常)是特定类型的标量值,例如数字、字符串或日期。

      Oracle 没有boolean 数据类型。因此,您不能将布尔表达式的结果分配给变量。您也不能从 case 表达式中返回它。但你的逻辑正试图这样做。

      一般来说,不鼓励在 SQL 中使用 case 表达式,因为它们会阻碍优化器。在你的情况下,你不需要一个。您的外部逻辑应该在 SQL 字符串外部分配方法比较逻辑。然后,为真的一个条件应该进入 SQL 表达式。不这样做的唯一原因是如果您将 SQL 字符串存储在某个地方,那么它将在不同的时间运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-03
        • 2012-09-16
        • 1970-01-01
        • 2012-07-26
        • 1970-01-01
        相关资源
        最近更新 更多