2

编辑以获得更好的说明:


2009 年 1 月 28 日补充:为了便于解释,我过度简化了代码,但是 select 语句很长很复杂,第二个依赖于第一个游标完成并循环后的第一个含义,并且插入创建第二个选择实际上将第一个插入视为 where 子句的一部分。

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

再次感谢。


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

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

我在下面创建了一个带有 4 个循环的示例,但正如您所见,它们都是相同的,唯一的区别是: For r in c1 loop, For r in c2 loop ...我认为必须有某种方式可以重用循环。我有一些想法,但都没有奏效。

 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;
4

5 回答 5

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;

再次感谢所有给出答案并调查问题的人,不胜感激

于 2009-01-30T18:34:04.047 回答
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;
于 2009-01-27T20:12:58.893 回答
0

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

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;
于 2009-01-27T19:54:33.547 回答
0

做就是了:

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

不需要游标循环。

于 2009-01-27T20:06:31.323 回答
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)
...
于 2009-01-27T20:18:08.727 回答