【问题标题】:Using CASE statement in where clause having parameters在具有参数的 where 子句中使用 CASE 语句
【发布时间】:2022-01-07 18:11:53
【问题描述】:

我正在创建 oracle 报告,如果用户输入 true 或 false,则相应的值应该转到参数。如果用户输入 All,那么 true 和 false 都应该进入参数。

我以 3 种方式使用了以下 case 语句。他们都显示缺少关键字错误。你能帮我解决这个问题吗?

WHERE "EngExec Status" = ((:eng_exec_status = 'True' and "EngExec Status" = 'True') 
                           OR (:eng_exec_status = 'False' AND "EngExec Status" = 'False') 
                           OR (:eng_exec_status = 'All' AND  ("EngExec Status" = 'True' OR "EngExec Status"= 'False')))
                         
WHERE "EngExec Status" IN (CASE 
                               WHEN (:eng_exec_status) = 'True' THEN "EngExec Status"= 'True'
                               WHEN (:eng_exec_status) = 'False' THEN "EngExec Status"= 'False'
                               ELSE "EngExec Status" IN ('True', 'False')  
                           END) 

WHERE "EngExec Status" IN (CASE 
                               WHEN (:eng_exec_status) = 'All' THEN "EngExec Status" IN ('True','False')
                               ELSE (:eng_exec_status)   
                           END)         

【问题讨论】:

  • 因为 case 是一个表达式,它应该返回一个标量。 Oracle 没有布尔数据类型,所以case 不能返回"EngExec Status"= 'True'
  • 还有一个问题:如果它有布尔值,你期望得到什么样的过滤器:where "EngExec Status" = "EngExec Status"= 'True'

标签: sql oracle obiee


【解决方案1】:

我的猜测是你想要一些简单的东西

WHERE ( :eng_exec_status = 'All' )
   OR ( :eng_exec_status = "EngExec Status" )

【讨论】:

    【解决方案2】:

    你的第一个sn-p:

    WHERE "EngExec Status" = ((:eng_exec_status = 'True' and "EngExec Status" = 'True') 
                               OR (:eng_exec_status = 'False' AND "EngExec Status" = 'False') 
                               OR (:eng_exec_status = 'All' AND  ("EngExec Status" = 'True' OR "EngExec Status"= 'False')))
    

    因为你有 WHERE column_value = (<boolean_expression>) 而失败,这是无效的语法。您可以在开头删除"EngExec Status" =

    WHERE (:eng_exec_status = 'True'  AND "EngExec Status" = 'True') 
    OR    (:eng_exec_status = 'False' AND "EngExec Status" = 'False') 
    OR    (:eng_exec_status = 'All'   AND ("EngExec Status" = 'True' OR "EngExec Status"= 'False'))
    

    第二个 sn-p 有 CASE 表达式:

    CASE 
    WHEN (:eng_exec_status) = 'True' THEN "EngExec Status"= 'True'
    WHEN (:eng_exec_status) = 'False' THEN "EngExec Status"= 'False'
    ELSE "EngExec Status" IN ('True', 'False')  
    END
    

    它应该有语法:

    CASE WHEN comparison_expr THEN return_expr [...] ELSE expr END
    

    还有from the documentation:

    对于简单和搜索的CASE 表达式,所有return_exprs 必须具有相同的数据类型(CHARVARCHAR2NCHARNVARCHAR2NUMBERBINARY_FLOATBINARY_DOUBLE) 或都必须具有数字数据类型。

    您的返回值不包含任何这些数据类型,而是使用了比较表达式。

    Oracle 抱怨“缺少关键字错误”,因为它期望在 THENELSE 子句中的 "EngExec Status" 之后出现 WHENELSEEND 关键字(因为它无效将比较表达式放在该位置,因此 =IN 运算符以及它们后面的表达式是无效的语法)。


    您的第三个 sn-p 失败的原因与第二个类似。


    如果您在"EngExec Status" 列上有一个CHECK 约束,将值限制为'True''False',那么您可以将WHERE 过滤器简化为:

    WHERE :eng_exec_status = "EngExec Status" OR :eng_exec_status = 'All'
    

    如果您没有 CHECK 约束来限制值,那么您可以使用:

    WHERE "EngExec Status" IN ('True', 'False')
    AND   (:eng_exec_status = "EngExec Status" OR :eng_exec_status = 'All')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      相关资源
      最近更新 更多