可选参数作为游标中的条件 (PL/SQL)

Posted

技术标签:

【中文标题】可选参数作为游标中的条件 (PL/SQL)【英文标题】:Optional Parameters as Condition in a Cursor (PL/SQL) 【发布时间】:2014-02-28 00:26:07 【问题描述】:

我有一个带有可选参数的函数/过程。如果提供,我需要将参数用作游标的条件。如果没有提供,那么我不想要那个条件。

这是我想出的一个非常简化的版本:

create or replace procedure check_data
  (p_parm1 in varchar2 default null,
   p_parm2 in number default null)
is
begin
  if (p_parm1 is null && p_parm2 is null) then
    for rec in (select col_1, col_2
        from table_a)
    loop
      /*Statements, use rec.col_1 and rec.col_2 */
    end loop;
  elsif (p_parm1 is null) then
    for rec in (select col_1, col_2
                from table_a
                where /*condition using p_parm2 */)
    loop
      /*Statements, use rec.col_1 and rec.col_2 */
    end loop;
  elsif (p_parm2 is null) then
    for rec in (select col_1, col_2
                from table_a
                where /*condition using p_parm1 */)
    loop
      /*Statements, use rec.col_1 and rec.col_2 */
    end loop;
  else
    for rec in (select col_1, col_2
                from table_a
                where /*condition using p_parm1 */
                  and /*condition using p_parm2 */)
  loop
      /*Statements, use rec.col_1 and rec.col_2 */
    end loop;
  end if;
end;

有没有办法让光标一次并指出如果没有提供参数则忽略哪些条件?

【问题讨论】:

【参考方案1】:

您可以让查询一次性处理所有场景,例如:

select col_1, col_2
from table_a
where (p_parm1 IS NULL OR (p_parm1 = ...))
AND   (p_parm2 IS NULL OR (p_parm2 = ...));

【讨论】:

我会试试这个。我建议了一个 COALESCE 函数,并在未提供时将变量设置为通配符,ei: v_variable1 := COALESCE(p_parm1, '%'); /* 然后在 where 子句中 */ where 表达式 LIKE v_variable1;但这会导致需要很长时间才能返回的大规模表扫描。我担心的是一个查询所有场景都会有相似的性能,但我会尝试一下。谢谢!【参考方案2】:

也可以用nvl,短一点:

select col1, col2
from table_a
where col1 = nvl(p_parm1,col1)
and col2 = nvl(p_parm2,col2);

所以你要做什么:当 p_parm1 为空时,你等于条件的列(在你比较 col1 和 p_parm1 的情况下)。

【讨论】:

我显然需要 15 声望才能投票,但这种方法确实有效。我认为当我选择一个视图时,我的效率会受到很大的影响,但也许我可以解决这个问题。这个概念很有效,让我开始寻找解决方案。非常感谢!【参考方案3】:
create or replace procedure check_data
  (p_parm1 in varchar2 default null,
   p_parm2 in number default null)
is
begin
    select col1, col2
    from table_a
    where (CASE
      WHEN (p_parm1 IS NOT NULL AND col1 = p_parm1) THEN (1)
      WHEN (p_parm1 IS NULL) THEN (1)
      ELSE 0
    END) = 1

如果需要,p_parm2 也一样。

【讨论】:

以上是关于可选参数作为游标中的条件 (PL/SQL)的主要内容,如果未能解决你的问题,请参考以下文章

where 条件中的可选参数 - 如何提高性能 - PL/SQL

使用执行立即参数和可选参数在 PL/SQL 中创建对象实例

ORACLE PL/SQL:函数和可选参数,如何?

游标 where 子句中的可选参数

可选输出光标作为参数

PL/SQL 游标使用参数作为列名