繁体   English   中英

PL/SQL 中参数化游标的意义何在?

[英]What's the point of parameterized cursors in PL/SQL?

有人能解释一下在 PL/SQL 中使用参数化游标而不是仅仅创建一个变量并在内部使用它的意义何在?

以下匿名块显示了我的意思:

DECLARE
    num NUMBER := 1;
    CURSOR d1 (p_num IN NUMBER) IS SELECT 'foo' FROM dual WHERE 1 = p_num;
    CURSOR d2 IS SELECT 'foo' FROM dual WHERE 1 = num;
BEGIN
    NULL;
END;

游标 d1 和 d2 之间在处理/性能/等方面有什么不同吗?

提前致谢。

您可能直到运行时才知道您的p_num值。 它可能是您从其他处理、另一个表、客户端环境或以某种方式计算得到的东西。

作为一个简单的例子:

declare
  cursor c1 is
    select * from departments;
  cursor c2 (p_department_id employees.department_id%type) is
    select * from employees
    where department_id = p_department_id;
begin
  for r1 in c1 loop
    -- do something with this department info
    dbms_output.put_line(r1.department_name);

    -- now loop through empoyees in that department
    for r2 in c2 (r1.department_id) loop
      -- do something with this employee info
      dbms_output.put_line('  ' || r2.first_name);
    end loop;
  end loop;
end;
/

Administration
  Jennifer
Marketing
  Michael
  Pat
Purchasing
  Den
  Alexander
...

c2游标正在寻找单个部门中的员工,但不能进行硬编码。

您可以使用d2构造的等效项执行相同的操作,即分配一个单独的局部变量,内部游标仍将使用该变量 - 因为它正在重新打开并在此时评估变量:

declare
  l_department_id departments.department_id%type;
  cursor c1 is
    select * from departments;
  cursor c2 is
    select * from employees
    where department_id = l_department_id;
begin
  for r1 in c1 loop
    -- do something with this department info
    dbms_output.put_line(r1.department_name);
    -- ...

    -- now loop through empoyees in that department
    l_department_id := r1.department_id;
    for r2 in c2 loop
      -- do something with this employee info
      dbms_output.put_line('  ' || r2.first_name);
    end loop;
  end loop;
end;
/

...但有一个参数可以更清楚地表明该值预计会发生变化,并避免了两次调用而忘记更改中间值的可能性。

在这两种情况下,游标查询的实际 SQL 将被视为具有绑定变量; 不同之处在于它是如何填充的。


很明显,您不会真正使用嵌套循环或任何 PL/SQL 来执行此特定任务; 并且在很多地方使用这种构造也同样适用,或者查询至少可以通过连接组合成单个游标。

对于更复杂的逻辑,它仍然很有用,例如,代码可以采用多条路径和多个可选的辅助游标,并且都需要来自相同(昂贵)基本查询的信息,并且您不想重复加入到基表。

与大多数逐行处理一样,我怀疑它被滥用的频率比真正必要的要高。 尽管如此,它仍然是一个有用的工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM