代码之家  ›  专栏  ›  技术社区  ›  Dan

将不同(多个)游标传递给同一for循环

  •  2
  • Dan  · 技术社区  · 16 年前

    为了更好的澄清而编辑:


    添加1/28/09:我对代码进行了过度简化以便于解释,但是select语句非常长而且复杂,第二个语句依赖于第一个含义,在第一个光标完成并循环通过并创建插入之后,第二个select实际上查看第一次插入是where子句的一部分。

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

    再次感谢。


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

    我的问题是,我有4个不同的选择,但我想重新使用循环,使我可以有光标C2利用相同的循环以及C3和C4。所有这些都是从非常不同的select中获取不同信息的游标,但是它们都与循环中的insert语句一起进入同一个表。另外,我不能将所有的select连接在一起,必须在每个循环之后使用commit来完成它们

    我用下面的4个循环创建了一个例子,但是你们可以看到它们都是一样的,唯一的区别是:对于R在C1环中,对于R在C2环中… 我想一定有办法再利用这个循环。我有一些想法,但都不管用。

     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 回复  |  直到 13 年前
        1
  •  1
  •   Mark Brady    16 年前

    或者只是这样做:

    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;
    
        2
  •  1
  •   da    16 年前

    如果有人需要知道怎么做的话,这里有一个可行的答案。 就像我办公室里另一个做过研究的人给我的:

    我创建了一个包含两个过程的包 第一个是多个游标,第二个是循环 (我对选择和插入进行了过度简化,以显示它是如何完成的)

    第一个过程称为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;
    

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

        3
  •  0
  •   Thomas Jones-Low    16 年前

    因此,您将得到以下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;
    
        4
  •  0
  •   tuinstoel    16 年前

    只做:

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

    不需要游标循环。

        5
  •  0
  •   Ricardo Villamil    16 年前

    为什么不动态地构建游标查询并且只使用一个游标呢?

    我假设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)
    ...
    
    推荐文章