Oracle PL SQL-动态定义全局游标

Oracle PL SQL-动态定义全局游标,oracle,plsql,Oracle,Plsql,在包的顶部有两个光标 cursor cur1() select 1 from dual; cursor cur2() select 2 from dual; 我有一个循环,如下所示,我尝试动态设置cur1或cur2 for row1 in cur1 -- or cur2 .. end loop; 或者我可以在顶部动态生成全局游标吗?假设两个游标的结果集是相同的列和数据类型,您可以执行以下操作: cursor cur(p_flag varchar2) is select

在包的顶部有两个光标

cursor cur1()
   select 1 from dual;

cursor cur2()
   select 2 from dual;
我有一个循环,如下所示,我尝试动态设置cur1或cur2

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

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

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

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;

其中,据推测,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.

Oracle提供了ref cursor构造,允许我们动态定义游标。不幸的是,我们不能在FOR循环中使用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;
/

查看。

你不能只设置一个“IF-THEN-ELSE-END-IF”条件,然后根据你选择的条件打开其中一个吗?我想这个解决方案,但我想知道是否可以动态设置?你如何决定使用哪个光标?例如,第一个光标是cur_Android,第二个光标是cur_IPhone。然后我想循环第一个游标[或第二个游标]。我可以动态地决定它吗?但是是什么决定了运行哪个游标呢?比如说,你有一个变量或者什么东西可以保存一个值,比如说Android或者Iphone?如果是的话,那么你可以在你的If语句中使用它,例如如果v_phone_type='Android',那么cur1中的第1行。。。elsif v_phone_type='Iphone',则对于cur2中的第1行。。。。如果两个游标for循环中都有逻辑,则可以将其放在单独的过程中,然后从任一循环中调用它。
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;
/