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

where子句中的Oracle和可选存储过程参数,oracle,stored-procedures,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 nu

我有一个带有如下可选参数的存储过程

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
子句非常长且复杂,因此我更喜欢使用“flexible”
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

这可能吗?

在这种情况下,您可以执行以下操作:

where param1=123 and (param2 is null or param2 != some_value)
如果param2不为null-则仅当
param2!=一些\u值
-如预期的那样

如果param2为null-则无论某个值是什么,它都返回true。最初我们使用以下语法:

WHERE (pParameter = COLUMN OR pParameter IS NULL)
直到数据库调优专家发现这会导致Oracle执行完整表扫描并忽略索引,因为使用或

现在我们使用

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')
或者,示例用例:

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