Oracle PL/SQL BULK COLLECT: FORALL Beispiel
โก Intelligente Zusammenfassung
MENGENABHOLUNG in Oracle PL/SQL lรคdt viele Zeilen gleichzeitig in eine Sammlung, wรคhrend FORALL groรe DML-Operationen an die Datenbank zurรผcksendet. Beide reduzieren Kontextwechsel zwischen SQL- und PL/SQL-Engines und steigern so die Performance.

Was ist BULK COLLECT?
BULK COLLECT reduziert Kontextwechsel zwischen den 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, Datensรคtze in groรen Mengen anstatt einzeln abzurufen. Diese BULK COLLECT-Anweisung kann in einer SELECT-Anweisung verwendet werden, um Datensรคtze in groรen Mengen abzurufen oder um eine Cursor Da BULK COLLECT die Datensรคtze gesammelt abruft, muss die INTO-Klausel immer eine Variable vom Typ โCollectionโ enthalten. Der Hauptvorteil von BULK COLLECT besteht in der Leistungssteigerung durch die Reduzierung der Interaktion zwischen Datenbank und PL/SQL-Engine.
Syntax:
SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>; FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;
In der obigen Syntax wird BULK COLLECT verwendet, um die Daten aus den SELECT- und FETCH-Anweisungen zu sammeln.
FORALL-Klausel
Die FORALL-Anweisung fรผhrt Folgendes aus DML-Operationen Bei groรen Datenmengen. Es รคhnelt einer FOR-Schleife, mit dem Unterschied, dass Aktionen in einer FOR-Schleife auf Datensatzebene ausgefรผhrt werden, wรคhrend FORALL kein Schleifenkonzept kennt. Stattdessen werden alle Daten im angegebenen Bereich 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 sich zwischen dem unteren und dem oberen Bereich befinden.
LIMIT-Klausel
Das Konzept der Massensammlung lรคdt alle Daten als Paket in die Ziel-Sammlungsvariable, d. h. alle Daten werden in einem einzigen Schritt in die Sammlungsvariable eingefรผgt. Dies ist jedoch nicht empfehlenswert, wenn die Gesamtzahl der zu ladenden Datensรคtze sehr groร ist, da PL/SQL beim Laden der gesamten Daten mehr Sitzungsspeicher belegt. Daher ist es ratsam, die Grรถรe dieser Massensammlungsoperation zu begrenzen.
Diese Grรถรenbeschrรคnkung kann leicht durch die Einfรผhrung der ROWNUM-Bedingung in der SELECT-Anweisung erreicht werden, im Falle eines Cursors ist dies jedoch nicht mรถglich.
Um dies zu รผberwinden, Oracle hat die LIMIT-Klausel bereitgestellt, die die Anzahl der Datensรคtze definiert, die in den Massenversand einbezogen werden mรผssen.
Syntax:
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;
In der obigen Syntax verwendet die Cursor-Fetch-Anweisung die BULK COLLECT-Anweisung zusammen mit der LIMIT-Klausel.
BULK COLLECT-Attribute
รhnlich wie Cursorattribute verfรผgt BULK COLLECT รผber %BULK_ROWCOUNT(n), das die Anzahl der Zeilen zurรผckgibt, die in der n-ten DML-Anweisung der FORALL-Anweisung betroffen sind. Es gibt also die Anzahl der Datensรคtze an, die in der FORALL-Anweisung fรผr jeden einzelnen Wert der Sammlungsvariablen betroffen sind. Der Parameter 'n' gibt die Position des Wertes in der Sammlung an, fรผr den die Zeilenanzahl benรถtigt wird.
Beispiel 1: In diesem Beispiel werden wir alle Mitarbeiternamen aus der Tabelle โempโ mit BULK COLLECT projizieren und auรerdem das Gehalt aller Mitarbeiter mit FORALL um 5000 erhรถhen.
Der folgende Screenshot zeigt dieses BULK COLLECT- und FORALL-Beispiel zusammen mit seiner Ausgabe. Oracle.
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 salary=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 Erlรคuterung:
- Code Zeile 2: Deklaration des Cursors guru99_det fรผr die Anweisung 'SELECT emp_name FROM emp'.
- Code Zeile 3: Deklaration von lv_emp_name_tbl als Tabellentyp VARCHAR2(50).
- Code Zeile 4: Deklaration von lv_emp_name als lv_emp_name_tbl-Typ.
- Code Zeile 6: รffnen des Cursors.
- Code Zeile 7: Der Cursor wird mit BULK COLLECT und der LIMIT-Grรถรe von 5000 in die Variable lv_emp_name eingelesen.
- Code Zeile 8-11: Einrichten einer FOR-Schleife zum Ausgeben aller Datensรคtze in der Sammlung lv_emp_name.
- Code Zeile 12: Mit FORALL das Gehalt aller Mitarbeiter um 5000 erhรถhen.
- Code Zeile 14: Begehen der Transaktion.

