Oracle:WHERE的真正价值

时间:2018-11-08 18:36:15

标签: sql oracle

我正在函数内部构建SQL查询。函数参数是我在WHERE子句中使用的条件。参数也可以为null。

foo (1,2,3)           =>   SELECT x FROM y WHERE a=1 AND b=2 AND c=3;
foo (null, 2, null)   =>   SELECT x FROM y WHERE b=2;

我在代码中执行此操作的方法是在WHERE子句中添加第一个历史记录true(例如1 = 1或NULL为NULL或2> 1)

因此,我不需要处理第一个WHERE条件在“ WHERE”之后而所有其他条件在“ AND”之后的问题。

String sql="SELECT x FROM y WHERE 1=1";
if (a!=null)
{
  sql += " AND a="+a;
}

是否有比1 = 1更好的条件,或者我的其他样本明确具有始终为真的值? TRUE和FALSE不起作用。

6 个答案:

答案 0 :(得分:2)

即使没有条件,我也从未真正理解过强制where子句的方法。如果要构造逻辑,请组合条件。如果结果字符串为空,则完全省略where子句

许多应用程序语言都等效于concat_ws() -带分隔符的字符串连接(例如,Python中的join)。因此,省略where子句甚至不会导致代码复杂得多。

对于您的问题,Oracle没有布尔值,因此1=1可能是最常见的方法。

答案 1 :(得分:1)

使用NVL,以便您可以设置默认值。查找NVL或NVL2。两者都可能为您工作。 签出:http://www.dba-oracle.com/t_nvl_vs_nvl2.htm

答案 2 :(得分:1)

Oracle在SQL中不支持布尔类型。它存在于PL / SQL中,但不能在查询中使用。最简单的事情是1 = 1表示true,0 = 1表示false。我不确定优化程序是否会优化这些,但是我怀疑对性能的影响可以忽略不计。我使用了谓词数量直到运行时才未知的位置。

我认为这种构造优于使用<ng-container *ngFor='let key of firebaseObjectKeys(firebaseData)'> <h2>key: {{key}}</h2> <tbody> {{firebaseData[key] | json}} <tr *ngIf='firebaseData[key]'> <td><h3>{{firebaseData[key].slang}}</h3></td> <td>{{firebaseData[key].slangDefine}}</td> <td> <a routerLink="'/admin/products/{{key}}">Edit {{key}}</a> </td> </tr> </tbody> </ng-container> nvlcoalescedecode的任何构造,因为这些绕过普通索引并且我已经将它们引向复杂而缓慢的执行计划。

所以,是的,我会做类似您的事情(不确定要使用哪种语言构建此查询;这不是有效的PL / SQL。您也应该使用绑定变量,但这是另一回事了)

case

我认为这比Gordon Linoff的建议要好,因为否则将更加复杂,因为您必须为每个谓词使用另一个子句来检查是否存在先前的谓词,即是否需要包含{{1 }} 或不。只是使代码更加冗长,从而避免在查询中使用单个琐碎的子句。

答案 3 :(得分:0)

在sql中,“默认null”的标准方法是使用合并。因此,假设您输入的是@ p1,@ p2和@ p3

然后

 select *
 from table
 where a = coalesce(@p1,a) and 
       b = coalesce(@p2,b) and 
       c = coalesce(@p3,c)

因此,如果(例如)@ p1为null,则它将比较a = a(始终为true)。如果@ p1不为null,则将按等于该值的值进行过滤。

通过这种方式,null成为所有记录的“通配符”。

答案 4 :(得分:0)

您还可以使用解码来获得所需的结果,因为它是oracle

Select 
decode(a, 1, x,null),
decode(b, 2, x,null),
decode(c, 3, x,null)
from y

答案 5 :(得分:0)

在括号内有OR的情况下在括号内使用AND怎么办

SELECT x 
  FROM y 
 WHERE ( a=:prm1 OR :prm1 is null) 
   AND ( b=:prm2 OR :prm2 is null) 
   AND ( c=:prm3 OR :prm3 is null);