Oracle PL/SQL BULK COLLECT: FORALL Beispiel
Was ist BULK COLLECT?
BULK COLLECT reduziert Kontextwechsel zwischen SQL und PL/SQL-Engine und ermรถglicht es der SQL-Engine, die Datensรคtze auf einmal abzurufen.
Oracle PL/SQL bietet die Funktionalitรคt, die Datensรคtze in groรen Mengen abzurufen, anstatt sie einzeln abzurufen. Dieses BULK COLLECT kann in der SELECT-Anweisung verwendet werden, um die Datensรคtze in groรen Mengen aufzufรผllen oder den Cursor in groรen Mengen abzurufen. Da BULK COLLECT den Datensatz in BULK abruft, sollte die INTO-Klausel immer eine Variable vom Typ Sammlung enthalten. Der Hauptvorteil der Verwendung von BULK COLLECT besteht darin, dass die Leistung erhรถht wird, indem die Interaktion zwischen Datenbank und PL/SQL-Engine reduziert wird.
Syntax:
SELECT <columnl> BULK COLLECT INTO bulk_varaible FROM <table name>; FETCH <cursor_name> BULK COLLECT INTO <bulk_varaible >;
In der obigen Syntax wird BULK COLLECT zum Sammeln der Daten aus den Anweisungen โSELECTโ und โFETCHโ verwendet.
FORALL-Klausel
Mit FORALL kรถnnen Sie DML-Operationen auf Daten in groรen Mengen ausfรผhren. Es รคhnelt der FOR-Schleifenanweisung, auรer in FOR-Schleife Dinge passieren auf der Datensatzebene, wรคhrend es in FORALL kein LOOP-Konzept gibt. Stattdessen werden alle im angegebenen Bereich vorhandenen Daten gleichzeitig verarbeitet.
Syntax:
FORALL <loop_variable>in<lower range> .. <higher range> <DML operations>;
In der obigen Syntax wird die angegebene DML-Operation fรผr alle Daten ausgefรผhrt, die zwischen dem unteren und oberen Bereich liegen.
LIMIT-Klausel
Das Bulk-Collect-Konzept lรคdt die gesamten Daten in groรen Mengen in die Ziel-Collection-Variable, d. h. die gesamten Daten werden auf einmal in die Collection-Variable eingetragen. Dies ist jedoch nicht ratsam, wenn der Gesamtdatensatz, der geladen werden muss, sehr groร ist, denn wann PL / SQL versucht, die gesamten Daten zu laden, verbraucht es mehr Sitzungsspeicher. Daher ist es immer gut, die Grรถรe dieses Massenerfassungsvorgangs zu begrenzen.
Diese Grรถรenbeschrรคnkung kann jedoch leicht durch die Einfรผhrung der ROWNUM-Bedingung in der SELECT-Anweisung erreicht werden, wรคhrend dies im Fall des Cursors nicht mรถglich ist.
Um dies zu รผberwinden Oracle hat die Klausel โLIMITโ bereitgestellt, die die Anzahl der Datensรคtze definiert, die in die Masse aufgenommen werden mรผssen.
Syntax:
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;
In der obigen Syntax verwendet die Cursor-Abrufanweisung die BULK COLLECT-Anweisung zusammen mit der LIMIT-Klausel.
BULK COLLECT-Attribute
รhnlich Cursor Attribute BULK COLLECT haben %BULK_ROWCOUNT(n), das die Anzahl der betroffenen Zeilen im n zurรผckgibtth DML-Anweisung der FORALL-Anweisung, dh sie gibt die Anzahl der betroffenen Datensรคtze in der FORALL-Anweisung fรผr jeden einzelnen Wert aus der Sammlungsvariablen an. Der Begriff โnโ gibt die Wertefolge in der Sammlung an, fรผr die die Zeilenanzahl benรถtigt wird.
Beispiel 1: In diesem Beispiel projizieren wir mit BULK COLLECT alle Mitarbeiternamen aus der emp-Tabelle und erhรถhen mit FORALL auch das Gehalt aller Mitarbeiter um 5000.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; TYPE lv_emp_name_tbl IS TABLE OF VARCHAR2(50); lv_emp_name lv_emp_name_tbl; BEGIN OPEN guru99_det; FETCH guru99_det BULK COLLECT INTO lv_emp_name LIMIT 5000; FOR c_emp_name IN lv_emp_name.FIRST .. lv_emp_name.LAST LOOP Dbms_output.put_line(โEmployee Fetched:โ||c_emp_name); END LOOP: FORALL i IN lv_emp_name.FIRST .. lv emp_name.LAST UPDATE emp SET salaiy=salary+5000 WHERE emp_name=lv_emp_name(i); COMMIT; Dbms_output.put_line(โSalary Updatedโ); CLOSE guru99_det; END; /
Ausgang
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Salary Updated
Code-Erklรคrung:
- Codezeile 2: Deklarieren des Cursors guru99_det fรผr die Anweisung โSELECT emp_name FROM empโ.
- Codezeile 3: Deklarieren von lv_emp_name_tbl als Tabellentyp von VARCHAR2(50)
- Codezeile 4: lv_emp_name wird als lv_emp_name_tbl-Typ deklariert.
- Codezeile 6: รffnen des Cursors.
- Codezeile 7: Abrufen des Cursors mit BULK COLLECT mit der LIMIT-Grรถรe als 5000 intl lv_emp_name-Variable.
- Codezeile 8-11: Einrichten einer FOR-Schleife zum Drucken aller Datensรคtze in der Sammlung lv_emp_name.
- Codezeile 12: Mit FORALL wird das Gehalt aller Mitarbeiter um 5000 aktualisiert.
- Codezeile 14: Bestรคtigen der Transaktion.

