【问题标题】:Oracle and optional stored procedure parameter in where clauseOracle 和 where 子句中的可选存储过程参数
【发布时间】:2013-07-25 08:12:49
【问题描述】:

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

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

这可能吗?

【问题讨论】:

    标签: oracle stored-procedures


    【解决方案1】:

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

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

    如果 param2 不为 null - 则仅当 param2 != some_value 为 true - 符合预期
    如果 param2 为 null - 那么无论 some_value 是什么,它都会返回 true

    【讨论】:

      【解决方案2】:

      最初我们使用这种语法:

      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
      

      【讨论】:

        猜你喜欢
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 2010-10-16
        • 1970-01-01
        • 2023-04-05
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多