3

我有一个带有像这样的可选参数的存储过程

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

这可能吗?

4

2 回答 2

4

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

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

如果 param2 不为 null - 那么只有当param2 != some_value- 符合预期时才为 true
如果 param2 为 null - 那么无论是什么some_value都返回 true

于 2013-07-25T08:29:55.030 回答
1

最初我们使用这种语法:

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
于 2017-08-02T15:51:40.860 回答