2个参考游标用于同一数据集

时间:2019-03-08 20:39:09

标签: plsql

您能解释一下如何为同一结果集创建2个游标吗? 我有 类似于以下内容:

declare
   emp_id_c1 number;
   emp_id_c2 number;
   c1 sys_refcursor;
   c2 sys_refcursor;
begin
  open c1 for with x as select emp_id from emp;
  c2 := c1;      
  loop
   fetch c1 into emp_id_c1;
   dbms_output.put_line('some');
   loop
     fetch c2 into emp_id_c2;
       dbms_output();
    exit when c2%notfound;
   end loop;
   exit when c1%notfound;
  end loop;
end;

谢谢

2 个答案:

答案 0 :(得分:1)

我不知道您的目标是什么,但是我知道当您想使用两个游标进行嵌套循环时,您犯错误的机率高达99%。如果需要比较两个游标中的数据,请将它们组合到一个SQL查询中并进行处理。主要原因是性能。与纯SQL相比,嵌套循环可将性能降低100倍。例如,对于基于查询的游标

select column1 from table1 where <condition1>

select column2 from table2 where <condition2>

如果您需要对具有相同数据的行执行某些操作,请执行以下操作:

declare
  val1 number;
  val2 number;
  cursor c1 is
    select column1, column2
      from table1 t1 join table2 t2 on t1.column1 = t2.column2
     where <condition1> and <condition2>;
begin
  open c1;
  loop
    fetch c1 into val1, val2;
    exit when c1%notfound;
    dbms_output.put_line('some text to output');
  end loop;
end;

UPD
如果确实需要对同一数据进行两个嵌套循环,则可以独立打开第二个游标。在您的代码中,而不是

c2 := c1;

open c2 for ...

内部第一个循环:

open c1 for ...
loop
   fetch c1 into emp_id_c1;
   ...
   open c2 for ...
   loop
     ...
   end loop; -- inner loop
end loop; -- outer loop

答案 1 :(得分:0)

根据您对相同数据集的提问,先填充两个不同的游标,然后填充游标,然后您将遵循正确的方法:

  declare
   emp_id_c1 number;
   emp_id_c2 number;
   c1 sys_refcursor;
   c2 sys_refcursor;
begin    
  open c1 for 
  select EmpID from Table1;
   c2 := c1;      
  loop
   fetch c1 into emp_id_c1;
   dbms_output.put_line('Cusrsor 1 data');
   loop
     fetch c2 into emp_id_c2;
        dbms_output.put_line('Cusrsor 2 data');
       dbms_output.put_line(emp_id_c2);
    exit when c2%notfound;
   end loop;
   exit when c1%notfound;
  end loop;
end;