PL SQL-动态定义全局游标

时间:2018-07-20 13:01:56

标签: oracle plsql

程序包顶部有两个光标

cursor cur1()
   select 1 from dual;

cursor cur2()
   select 2 from dual;

我有如下循环,我尝试动态设置cur1或cur2。

for row1 in cur1 -- or cur2
  ..
end loop;

或者我可以动态地在顶部生成全局游标吗?

2 个答案:

答案 0 :(得分:1)

Oracle提供了ref游标构造,以允许我们动态定义游标。不幸的是,我们不能在FOR LOOP中使用ref游标,因此我们需要输入更多代码。

declare
    rc sys_refcursor;
    switch varchar2(10) := 'iOS';
    lrec t23%rowtype; -- or define a RECORD type to match the required projection
begin
    -- in real life SWITCH would be a passed parameter
    if switch = 'iOS' then
         open rc for select * from t23;
    else
         open rc for select * from t42;  
    end if;
    loop
        fetch rc into lrec;
        exit when rc%notfound;
        dbms_output.put_line(lrec.id ||'::'||lrec.text);
    end loop;
end;
/

签出the SQL Fiddle demo

答案 1 :(得分:0)

假设两个游标的结果集是相同的列和数据类型,则可以执行以下操作:

cursor cur(p_flag varchar2) is
  select 1 as value from dual
  where p_flag = 'iOS'
  union
  select 2 as value from dual
  where p_flag = 'Android';

然后

for row1 in cur('iOS')
  ...
end loop;

for row1 in cur('Android')
  ...
end loop;

大概是iOS / Android标志实际上是变量而不是文字。

游标并集的每个分支中的标志检查使该分支不返回任何行。希望优化器能够立即发现并短路,从而在死分支中实际上不做任何实际工作。

快速演示:

declare
  cursor cur(p_flag varchar2) is
    select 1 as value from dual
    where p_flag = 'iOS'
    union
    select 2 from dual
    where p_flag = 'Android';

  l_flag varchar2(7);
begin
  l_flag := 'Android';

  for r in cur(l_flag) loop
    dbms_output.put_line('Cursor got: ' || r.value);
  end loop;
end;
/

Cursor got: 2

PL/SQL procedure successfully completed.