Oracle和where子句中的可选存储过程参数

时间:2013-07-25 08:12:49

标签: oracle stored-procedures

我有一个带有像

这样的可选参数的存储过程
create or replace 
PROCEDURE "my_stored_procedure" (param1 int, param2 int default null)
IS

BEGIN 

[select some fields from some tables]
...

我需要一个where子句,在默认参数上设置if(如果已设置),但我甚至不知道它是否可能......

这样的东西
where param1=123 and (if param2 is not null then some_value != param2)

select条款很长很复杂,所以我更倾向于使用“灵活”WHERE而不是

这样的结构
if param2 is not null then
    [long and complex select] where param1=123 and some_value != param2
else
    [long and complex select] where param1=123

这可能吗?

2 个答案:

答案 0 :(得分:4)

在这种情况下,你可以这样做:

where param1=123 and (param2 is null or param2 != some_value)

如果param2不为空 - 那么只有当param2 != some_value - 正如预期的那样时才是真的 如果param2为null - 则无论some_value是什么

,它都返回true

答案 1 :(得分:0)

最初我们使用了这种语法:

WHERE (pParameter = COLUMN OR pParameter IS NULL)

直到数据库调优专家发现这导致Oracle执行全表扫描并忽略索引,因为使用了OR。

现在我们使用

WHERE decode(pParameter, 
             null, 1, --if parameter is null, then return 1
             COLUMN, 1, -- if parameter matches the value in the column, then return 1
             0) --else return 0
             = 1

此构造允许以简单易读的方式为特殊值添加特殊处理

WHERE decode(pParameter, 
     null, 1, --if parameter is null, then allow the row
     'abc', 1, --if parameter is 'abc', then always allow the row
     'xyz', 1, --if parameter is 'xyz', then always reject the row
     COLUMN, 1, -- if parameter matches the value in the column, then allow
         0) --else return 0 to reject the row
         = 1

或者,您可以使用COALESCE或CASE重写此内容:

WHERE COALESCE(pParameter, COLUMN, 'ok') = COALESCE(COLUMN, 'ok')

或使用CASE的样本:

THEN    (
            case 
            when pParameteris null then 1
            when pParameter= COLUMN then 1
            else 0
            end
        ) = 1