PL/SQL条件Where子句

3

我想在SQL语句中执行一个有条件的where,并使用两个不同的条件,例如伪代码:

procedure(..., bool_value IN boolean default false) is
....
begin

select * from mytable mt
where 
     if bool_value = true then mt.criterion_1 = value
     else
        mt_.criterion_2 = value; -- if boolean value is set, use criterion_1 column, otherwise use criterion_2 column

end

假设这是可能的,最好的方法是什么?
谢谢

shree.pat18和Nishanthi:感谢你们的解决方案,它有效!正如指出的那样,在Oracle中使用布尔测试是行不通的,因为SQL没有等效的数据类型。请参见http://docs.oracle.com/cd/E11882_01/appdev.112/e17126/datatypes.htm#LNPLS348。 - Carmellose
3个回答

10

试试这个:

bool_value_string varchar2(5)

bool_value_string = case when bool_value then 'true' else 'false' end;

select * from mytable mt
where 
(bool_value_string = 'true' and mt.criterion_1 = value)
or
(bool_value_string = 'false' and mt.criterion_2 = value)

基本上,将你的when...then习惯用语转换为either...or习惯用语。要么布尔字段是非空和true的,这意味着过滤器必须按照第一个标准进行过滤,要么不是,这意味着按照第二个标准进行过滤。


4
除非最近Oracle有所改变,否则bool_value = true不起作用;在SQL语句中无法使用布尔变量。 - Erich Kitzmueller
1
@ammoQ 这本来是伪代码,但你指出了布尔值的问题。我会更新我的答案以反映这一点。 - shree.pat18
2
@ammoQ 是的,非常感谢你指出这一点。现在我知道了,会尽量避免使用Oracle。 - simo.3792
1
bool_value is null 也不起作用,PLS-382: expression is of wrong type。你必须完全将布尔变量从 SQL 语句中排除。 - Erich Kitzmueller
1
@ammoQ 糟糕,忘记删除了。再次感谢。 - shree.pat18

2
基本上,您的状况被翻译为:
 if bool_value = true 
       then mt.criterion_1 = value
 else if bool_value = false
       then mt_.criterion_2 = value; 

由于在select语句中不能直接使用布尔值(参见注释),因此请按照以下方式使用:(将bool_value从布尔类型更改为varchar2或数字类型)

procedure(..., bool_value IN varchar2(10) default 'FALSE') is
....
begin

   select * from mytable mt
    where  
      (case 
          when (bool_value = 'TRUE' and mt.criterion_1 = value) then (1)
          when (bool_value = 'FALSE' and mt_.criterion_2 = value) then (1)
          (else 0)
      end) = 1;

OR

      select * from mytable mt
      where 
      (bool_value = 'TRUE' and mt.criterion_1 = value)
       or
      (bool_value = 'FALSE' and mt.criterion_2 = value)


end

您也可以在where子句中使用case语句,如下所示:
select * from mytable mt
where  
  (case 
      when (bool_value = true and mt.criterion_1 = value) then (1)
      when (bool_value = false and mt_.criterion_2 = value) then (1)
      (else 0)
  end) = 1;

在Oracle中,您也可以使用以下查询。
  select * from mytable mt
  where 
  (bool_value = true and mt.criterion_1 = value)
   or
  (bool_value = false and mt.criterion_2 = value)

注意:由于默认值为bool_value = false,因此无需检查is null条件。

在Oracle SQL语句中,您不能使用布尔变量或字面值truefalse - Erich Kitzmueller
@ammoQ和carmellose: https://dev59.com/HXM_5IYBdhLWcg3wPAjT - ngrashia

1

最简单的形式是这样的:

WHERE (bool_value = TRUE AND mt.criterion_1 = value)
OR (bool_value = FALSE AND mt.criterion_2 = value)

2
正如ammoQ在回复shree.pat18的答案中已经提到的那样,这不会起作用,因为Oracle不支持SQL中的布尔类型。 - Frank Schmitt
1
@FrankSchmitt 正如 shree.pat18 已经提到的,答案是以伪代码形式给出的,因为我们不知道 bool_value 的实际数据类型。 - simo.3792

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接