将不同(多个)游标传递给相同的For循环

时间:2009-01-27 17:02:06

标签: sql oracle oracle10g

编辑以便更好地澄清:


添加了1/28/09:我简化了代码以便于解释,但是select语句非常冗长和复杂,第二个依赖于第一个游标完成和循环后的第一个含义通过和插入创建第二个选择实际上查看第一个插入作为where子句的一部分。

这就是为什么我需要多次使用循环而不是以任何方式组合选择。 当我按照我想要调用它们的顺序调用它们时,我需要它们运行,这让我回到原来的问题,无论如何重新使用带有不同光标的循环?

再次感谢。


我正在创建一个包(Oracle 10),其中我有4个不同的select语句(可能还有更多),我创建了一个游标并获取我的数据。现在我通常会获取数据并创建一个For循环,一切都很顺利。

我的问题是我有4个不同的选择,但我想重新使用循环,这样我可以让光标c2使用相同的循环以及c3和c4。所有这些都是游标从非常不同的选择中获取不同的信息,但它们都在循环中使用我的insert语句进入同一个表。此外,我不能将所有选择加在一起,它们必须按顺序完成每个循环后的提交

我在下面创建了一个带有4个循环的示例但是你可以看到它们都是相同的,唯一的区别是:对于c1循环中的r,对于c2循环中的r ... 我认为必须有一些重用循环。我有一些想法,但没有一个有效。

 cursor c1 is  select info_a, info_b from table_x where info_g = 77; 
 cursor c2 is  select info-a, info_b from table_x where info_g = 88;
 cursor c3 is  select info-a, info_b from table_y where info_j = 88;
 cursor c4 is  select info-a, info_b from table_y where info_j = 99;


  Begin

     For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c2 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c3 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c4 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

   end;

希望这更有意义并且谢谢

我编辑了然后一些答案进来了......对不起。 原作看起来像这样:

 cursor c1 is  select some_info, other_info from some_table where where some_thing = 'xyz'; 
cursor c2 is select some_info, other_info from some_table where where some_thing = 'abc';

   For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.some_info, r.other_info);
    end loop;

5 个答案:

答案 0 :(得分:1)

或者只是做:

cursor c1 is  
select info_a, info_b from table_x where info_g IN (77, 88) UNION ALL
select info-a, info_b from table_y where info_j IN (88, 99);

Begin

     For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

END;

答案 1 :(得分:1)

这是一个有效的答案,如果有人需要知道如何做到这一点。 正如我办公室里另一位做过研究的人给我的那样:

我用2个程序创建了一个包 第一个是多个游标,第二个是循环 (我简化了选择并插入以显示它是如何完成的)

第一个名为Select_Cursor的程序:

procedure Select_Cursors is 

  the_cursor sys_refcursor;    -- this defines the_cursor as type sys_refcursor  

begin

 open the_cursor for 

     select  application_idn, account_idn     
      from accounts ac,  applications ha
     where  something = somethingelse

 Insert_Cursor ( the_cursor );  
 close the_cursor;

  open the_cursor for 

     select  application_idn, account_idn     
      from accounts ac,  applications ha
     where  somethingfunny = somethingcrazy

  Insert_Cursor ( the_cursor );  
 close the_cursor;


 ...  repeat for every select

 end Select_Cursors; 

第二个名为Insert_Cursor的过程是:

procedure Insert_Cursor ( p_cursor in sys_refcursor ) is


    begin

       loop
            fetch p_cursor into  application_idn, account_idn ;
            exit when p_cursor%notfound;

            insert into payments (issue_type_des, issued_amt, payment_Type_cde,payment_Status_Cde, created_by, application_idn, account_idn)
                 values          (v_paytype, v_amount, 'S','PE','This Process',  application_idn, account_idn);
       end loop;

       commit;

    end Insert_Cursor;

再次感谢所有给出答案并研究问题的人,感谢

答案 2 :(得分:0)

因此,您将拥有以下select语句:

select some_info, other_info from some_table where some_thing = 'xyz'; 
select c2_info, c2_other from c2_table where c2_thing = 'XYZ;'

您可以通过将c1声明为其他未知类型的SYS_REFCURSOR来执行此操作,并确保每个查询的所有列都属于相同类型(或接近它)。您不能使用行类型,您必须单独声明列,以及适用于所有查询的泛型类型。但以下确实有效。

DECLARE
  C1 SYS_REFCURSOR;
  TableID NUMBER;
  TableName VARCHAR2(240);
BEGIN

  OPEN C1 FOR select CALENDAR_ID, CALENDAR_NAME from CALENDARS;

  LOOP
    FETCH C1 INTO tableid, tablename;
    EXIT WHEN C1%NOTFOUND;
    DBMS_OUTPUT.put_line ('ID: ' || to_char(tableID) || ' -- NAME: ' || TableName);
  END LOOP;
  CLOSE C1;
  OPEN C1 for SELECT INIT_ID, NAME FROM INITS;  
  LOOP
    FETCH C1 INTO tableid, tablename;
    EXIT WHEN C1%NOTFOUND;
    DBMS_OUTPUT.put_line ('ID: ' || to_char(tableID) || ' -- NAME: ' || TableName);
  END LOOP;
  CLOSE C1;
END;

答案 3 :(得分:0)

只是做:

begin
  insert into cool_table 
  ( neat_info 
  , boring_info)
  select some_info
  ,      other_info 
  from some_table 
  where some_thing = 'XYZ';
end;

不需要游标循环。

答案 4 :(得分:0)

为什么不动态构建游标查询而只使用一个游标?

77,88和99来自存储过程的参数,我假设。

cursor c1 is  
select info_a, info_b from table_x where info_g in( 77, 88)
UNION
select info-a, info_b from table_y where info_j in (88, 99)
...