如果输入为NULL或输入为非NULL的特定记录,哪种方法更好地获取所有条目的输出? 这是针对Oracle数据库上的PL / SQL。让我知道我的第一种方法是否错误
select * from student where (roll_no = :ROLL_NO or :ROLL_NO is NULL);
OR
select * from student where roll_no = NVL(:ROLL_NO, roll_no);
答案 0 :(得分:5)
在roll_no
为空的情况下,这两种方法将给出不同的结果,因为对于这些行,roll_no = roll_no
将不成立。
如果有索引,则优化器具有somecol = nvl(:param,somecol)
的特殊情况,您将在执行计划中看到两个FILTER
操作和一个CONCATENATION
,表示{ {1}}为空或不为空。因此,只要将:param
定义为nvl
列,我就使用roll_no
表达式。
答案 1 :(得分:1)
通常,使用运算符是一种更好的方法。这是因为当列不是函数的参数时,优化器可以更聪明。
此答案假定roll_no
不是null
。
尽管有时可能会遇到Oracle优化器的情况,但是您可能会发现,当存在适当的索引时,使用union all
编写查询实际上会产生更好的执行计划:
select s.*
from student s
where roll_no = :ROLL_NO
union all
select s.*
from student s
where :ROLL_NO is NULL;
答案 2 :(得分:0)
第二种方法只需稍作修改即可得到相同的结果(无法将null与null进行比较):
select * from student where NVL(roll_no,1) = NVL(NVL(:ROLL_NO, roll_no),1);
答案 3 :(得分:0)
威廉·罗伯逊(William Robertson)提出了一个好观点。那我明白我的错误。 我尝试了Gordon Linoff的答案。有效。 我认为waldemort的答案也将是正确的,但我没有尝试过。
下面的答案是我对此的解决方案,它可能与waldemort的答案类似。
{{select * from student where AND (roll_no = nvl(roll_no,1) = nvl(:roll_no,1)
}
感谢帮助人员