2 Stimmen

Übergeben von verschiedenen (mehreren) Cursorn zur gleichen For-Schleife

Bearbeitet zur besseren Klarstellung:


Hinzugefügt am 28.01.09: Ich habe den Code vereinfacht, um ihn leicht zu erklären, aber die SELECT-Anweisungen sind sehr lang und kompliziert, und die zweite ist abhängig von der ersten, d.h. nachdem der erste Cursor durchlaufen wurde und die Inserts erstellt wurden, betrachtet die zweite SELECT tatsächlich die ersten Inserts als Teil des WHERE-Klausels.

Deshalb muss ich die Schleife mehr als einmal verwenden und die SELECT-Anweisungen nicht irgendwie kombinieren. Ich muss sie ausführen, wenn ich sie aufrufe, in der Reihenfolge, in der ich sie aufrufen möchte. Das bringt mich zurück zu meiner ursprünglichen Frage: Gibt es überhaupt eine Möglichkeit, eine Schleife mit einem anderen Cursor wiederzuverwenden?

Nochmals vielen Dank.


Ich erstelle ein Paket (Oracle 10), für das ich 4 verschiedene SELECT-Anweisungen (eventuell noch mehr) habe, für die ich jeweils einen Cursor erstelle und meine Daten abrufe. Normalerweise nehme ich die Daten und erstelle eine For-Schleife und alles läuft gut.

Mein Problem ist, dass ich 4 verschiedene SELECT-Anweisungen habe, aber ich möchte die Schleife wiederverwenden, damit Cursor c2, sowie c3 und c4 dieselbe Schleife nutzen können. All diese Cursor rufen verschiedene Informationen aus sehr unterschiedlichen SELECT-Anweisungen ab, aber sie werden alle mit meiner INSERT-Anweisung in der Schleife in dieselbe Tabelle eingefügt. Außerdem kann ich nicht alle SELECT-Anweisungen zusammenführen, sie müssen in der Reihenfolge mit einem COMMIT nach jeder Schleife ausgeführt werden.

Ich habe unten ein Beispiel mit 4 Schleifen erstellt, aber wie Sie sehen können, sind sie alle gleich, der einzige Unterschied ist: Für r in c1 loop, Für 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;

Hoffe das ergibt mehr Sinn und danke

Ich habe bearbeitet und dann kamen einige Antworten rein.. entschuldigung. Das Original sah ungefähr so aus:

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;

1voto

Oder einfach tun:

Kursor c1 ist  
wählen info_a, info_b von tabelle_x wo info_g IN (77, 88) UNION ALL
wählen info-a, info_b von tabelle_y wo info_j IN (88, 99);

Begin

     Für r in c1 schleife
        einfügen in spaß_tabelle (gute_info, langweilige_info) werte (r.info_a, r.info-b);
     end schleife;
    verpflichten;

END;

1voto

Hier ist eine Antwort, die funktioniert, falls jemand wissen möchte, wie man das macht. Wie mir von einem anderen Kollegen in meinem Büro mitgeteilt wurde, der etwas recherchiert hat:

Ich habe ein Paket mit 2 Prozeduren erstellt. Die erste ist die Mehrfachcursor, die zweite ist die Schleife (Ich habe die Selects und Inserts vereinfacht, um nur zu zeigen, wie es gemacht wird)

Die erste Prozedur heißt Select_Cursor:

Prozedur Select_Cursors ist 

  der_cursor sys_refcursor;    -- das definiert der_cursor als Typ sys_refcursor  

begin

 open der_cursor for 

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

 Insert_Cursor ( der_cursor );  
 close der_cursor;

  open der_cursor for 

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

  Insert_Cursor ( der_cursor );  
 close der_cursor;

 ...  wiederholen für jede select Anweisung

 end Select_Cursors; 

Die zweite Prozedur heißt Insert_Cursor:

Prozedur 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','Dieser Prozess',  application_idn, account_idn);
       end loop;

       commit;

    end Insert_Cursor;

Nochmals vielen Dank an alle, die eine Antwort gegeben haben und sich mit dem Problem beschäftigt haben, es wird geschätzt

0voto

Thomas Jones-Low Punkte 6881

Also werden Sie die folgenden Select-Anweisungen haben:

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

Sie tun dies, indem Sie c1 als SYS_REFCURSOR eines ansonsten unbekannten Typs deklarieren und sicherstellen, dass alle Spalten jeder Abfrage desselben Typs (oder einem ähnlichen) sind. Sie können keinen Reihentyp verwenden, Sie müssen die Spalten einzeln deklarieren und von einem generischen Typ, der auf alle Abfragen zutrifft. Aber das Folgende funktioniert.

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;

0voto

tuinstoel Punkte 7244

Einfach tun:

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

keine Cursor-Schleifen benötigt.

0voto

Ricardo Villamil Punkte 4924

Warum erstellen Sie Ihre Cursor-Abfrage nicht dynamisch und verwenden nur einen Cursor?

Woher kommen die Werte 77, 88 und 99, die als Parameter in Ihre gespeicherte Prozedur übergeben werden, nehme ich an.

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)
...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X