Передача разных (нескольких) курсоров в один цикл For Loop - PullRequest
2 голосов
/ 27 января 2009

Отредактировано для лучшего уточнения:


Добавлено 28.01.09: я слишком упростил код, чтобы его было легко объяснить, но операторы выбора очень длинные и сложные, а второй зависит от первого значения после того, как первый курсор сделан и зациклен и вставки созданы, второй выбор фактически рассматривает первые вставки как часть предложения where.

Вот почему мне нужно использовать цикл более одного раза и никоим образом не комбинировать выборки. Мне нужно, чтобы они запускались, когда я вызываю их в том порядке, в котором я хочу их вызывать, что возвращает меня к исходному вопросу: есть ли в любом случае повторное использование цикла с другим курсором?

Еще раз спасибо.


Я создаю пакет (Oracle 10), в котором у меня есть 4 различных оператора выбора (возможно, еще больше), для которых я создаю курсор и получаю свои данные. Теперь обычно я беру данные и создаю цикл For Loop, и все хорошо.

Моя проблема в том, что у меня есть 4 разных выбора, но я хочу повторно использовать цикл, чтобы курсор c2 мог использовать тот же цикл, а также c3 и c4. Все они являются курсорами, получающими различную информацию из самых разных селекторов, но все они попадают в одну таблицу с моим оператором вставки в цикле. Также я не могу объединить все выборки вместе, они должны быть выполнены в порядке с фиксацией после каждого цикла

Я создал приведенный ниже пример с 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 ]

1 голос
/ 30 января 2009

Вот ответ, который работает, если кто-то когда-либо должен знать, как это сделать. Как мне сказал другой парень из моего офиса, который провел какое-то исследование:

Я создал пакет с 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;

Еще раз спасибо всем, кто дал ответ и посмотрел на проблему, это ценится

1 голос
/ 27 января 2009

Или просто сделай:

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;
0 голосов
/ 27 января 2009

Почему бы не построить свой курсорный запрос динамически и использовать только один курсор?

Где 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)
...
0 голосов
/ 27 января 2009

Просто сделай:

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

петли курсора не нужны.

0 голосов
/ 27 января 2009

Итак, у вас будут следующие операторы выбора:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...