Oracle PL/SQL BULK COLLECT: FORALL Példa

⚡ Okos összefoglaló

TÖMEGES GYŰJTÉS Oracle A PL/SQL egyszerre sok sort kér le egy gyűjteménybe, míg a FORALL tömeges DML-t küld vissza az adatbázisba. Mindkettő megszünteti az SQL és a PL/SQL motorok közötti kontextusváltást, növelve a teljesítményt.

  • 📦 TÖMEGES GYŰJTÉS: Több sort kér le egyetlen menetben egy gyűjteményváltozóba, lecserélve a lassú soronkénti lekérést.
  • 🔁 MINDENKINEK: Egyetlen INSERT, UPDATE vagy DELETE parancsot futtat egy teljes gyűjteményen egyetlen kontextusváltással.
  • 📏 LIMIT záradék: Korlátozza a BULK COLLECT lekérésenkénti betölthető sorok számát, védve a munkamenet-memóriát a nagy táblákon.
  • 📊 TÖMEGES GYŰJTÉS Tulajdonságok: A %BULK_ROWCOUNT(n) attribútum azt mutatja, hogy az n-edik FORALL DML utasítás hány sort érintett.
  • 🇧🇷 Szükséges gyűjtemények: Az INTO záradéknak egy gyűjteménytípust kell céloznia, például beágyazott táblázatot vagy asszociatív tömböt.
  • 🤖 AI segítség: Az olyan mesterséges intelligencia asszisztensek, mint a GitHub Copilot, BULK COLLECT és FORALL blokkokat készítenek, és megjelölik a hiányzó LIMIT záradékot.

Oracle PL/SQL BULK COLLECT és FORALL LIMIT záradékkal – áttekintés

Mi az a BULK COLLECT?

A TÖMEGES GYŰJTÉS csökkenti a kontextusváltásokat a SQL és a PL/SQL motort, és lehetővé teszi az SQL motor számára, hogy egyszerre kérje le a rekordokat.

Oracle PL / SQL lehetővé teszi a rekordok tömeges lekérését az egyes lekérések helyett. Ez a BULK COLLECT használható egy SELECT utasításban a rekordok tömeges feltöltésére, vagy egy kurzor tömegesen. Mivel a BULK COLLECT tömegesen kéri le a rekordokat, az INTO záradéknak mindig tartalmaznia kell egy gyűjtemény típusú változót. A BULK COLLECT használatának fő előnye, hogy az adatbázis és a PL/SQL motor közötti interakció csökkentésével növeli a teljesítményt.

Syntax:

SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>;
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;

A fenti szintaxisban a BULK COLLECT utasítással gyűjtjük össze az adatokat a SELECT és FETCH utasításokból.

FORALL záradék

A FORALL utasítás végrehajtja DML-műveletek tömeges adatokon. Ez egy FOR ciklusutasításra hasonlít, azzal a különbséggel, hogy egy FOR ciklusban a műveletek rekordszinten történnek, míg a FORALL-ban nincs LOOP koncepció. Ehelyett az adott tartományban lévő összes adat egyszerre kerül feldolgozásra.

Syntax:

FORALL <loop_variable> in <lower range> .. <higher range>

<DML operations>;

A fenti szintaxisban a megadott DML művelet az alsó és felső tartomány közötti összes adatra végrehajtódik.

LIMIT záradék

A tömeges gyűjtés koncepciója a teljes adatmennyiséget tömegesen tölti be a célgyűjtemény változóba, azaz a teljes adatmennyiség egyszerre kerül feltöltésre a gyűjtemény változóba. Ez azonban nem ajánlott, ha a betöltendő rekordok teljes száma nagyon nagy, mert amikor a PL/SQL megpróbálja betölteni a teljes adatmennyiséget, több munkamenet-memóriát fogyaszt. Ezért mindig érdemes korlátozni a tömeges gyűjtési művelet méretét.

Ez a méretkorlát könnyen elérhető a ROWNUM feltétel bevezetésével a SELECT utasításban, míg kurzor esetén ez nem lehetséges.

Ennek leküzdésére, Oracle biztosította a LIMIT záradékot, amely meghatározza a tömegesen befogadandó rekordok számát.

Syntax:

FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;

A fenti szintaxisban a kurzor lehívási utasítása a BULK COLLECT utasítást használja a LIMIT záradékkal együtt.

BULK COLLECT Tulajdonságok

A kurzor attribútumokhoz hasonlóan a BULK COLLECT függvény %BULK_ROWCOUNT(n) függvénnyel tér vissza a FORALL utasítás n-edik DML utasításában érintett sorok számát, azaz a gyűjteményváltozó minden egyes értékére megadja a FORALL utasításban érintett rekordok számát. Az 'n' tag a gyűjteményben lévő érték sorrendjét jelzi, amelyhez a sorszám szükséges.

Példa 1: Ebben a példában a BULK COLLECT segítségével kivetítjük az összes alkalmazott nevét az emp táblából, és a FORALL használatával 5000-rel megnöveljük az összes alkalmazott fizetését.

Az alábbi képernyőkép ezt a BULK COLLECT és FORALL példát mutatja be a kimenetével együtt. Oracle.

TÖMEGES GYŰJTÉS LIMIT és FORALL használatával, példa az alkalmazottak fizetésének frissítésére Oracle PL / SQL

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;
/

teljesítmény

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Salary Updated

Code Magyarázat:

  • Code 2. sor: A guru99_det kurzor deklarálása a 'SELECT emp_name FROM emp' utasításhoz.
  • Code 3. sor: Az lv_emp_name_tbl deklarálása VARCHAR2(50) típusú táblaként.
  • Code 4. sor: Az lv_emp_name deklarálása lv_emp_name_tbl típusként.
  • Code 6. sor: A kurzor megnyitása.
  • Code 7. sor: A kurzor lekérése a BULK COLLECT paranccsal, 5000-es LIMIT mérettel az lv_emp_name változóba.
  • Code 8-11. sor: FOR ciklus beállítása az lv_emp_name gyűjtemény összes rekordjának kinyomtatására.
  • Code 12. sor: A FORALL használata az összes alkalmazott fizetésének 5000-rel történő frissítéséhez.
  • Code 14. sor: Elkötelezve a tranzakció.

GYIK

Nem. A BULK COLLECT SELECT soha nem eredményez NO_DATA_FOUND hibát; ehelyett egy üres gyűjteményt ad vissza. Mindig tesztelje a gyűjteményt a .COUNT metódussal, mielőtt elkezdené.ping, ellenkező esetben előfordulhat, hogy nulla sort dolgoz fel csendben.

A SAVE EXCEPTIONS paranccsal a FORALL függvény továbbra is futhat, ha egyes sorok meghibásodnak. A meghibásodott sorok az SQL%BULK_EXCEPTIONS fájlban tárolódnak, majd Oracle ORA-24381-et emel, amelyet egy kivétel kezelő minden egyes hibát megvizsgál.

Használd a BULK COLLECT függvényt, ha egy ciklus sok sort olvas be. kurzor A FOR ciklus kapcsolónként egy sort kér le, így a tömeges lekérés a FORALL-lal együtt sokkal gyorsabban futhat nagy eredményhalmazokon.

A BULK COLLECT egyszerre sok sort ad vissza, ezért többsoros konténerre van szüksége. Az INTO célnak egynek kell lennie. gyűjtemény például beágyazott tábla, VARRAY vagy asszociatív tömb, nem egyetlen skaláris változó.

Nem. Egy FORALL fejléc pontosan egy INSERT, UPDATE, DELETE vagy MERGE utasítást vezérel. Csak a VALUES és WHERE záradékokban lévő értékek változhatnak iterációnként. Több utasítás esetén külön FORALL utasításokat kell használni.

A tömeges feldolgozás többszörösen, akár több mint százszor gyorsabb is lehet, mint a soronkénti kódfeldolgozás, mivel a BULK COLLECT és a FORALL több ezer motorkontextus-kapcsolót néhányra omlaszt össze, jelentősen csökkentve a nagy adatmennyiségek terhelését.

Igen. GitHub másodpilóta A BULK COLLECT lehívásokat, FORALL DML ciklusokat és LIMIT záradékokat készít egy megjegyzésből, és javaslatokat tesz a gyűjteménytípus-deklarációkra, bár a kötegek méretét és a hibakezelést érdemes Önnek is áttekintenie.

A mesterséges intelligencia asszisztensek beolvassák a soronként lekérő vagy módosító ciklusokat, és BULK COLLECT, LIMIT és FORALL utasításokkal javasolják azok újraírását. Ez a gépi tanulással végzett áttekintés a hiányzó LIMIT korlátozásokat és a teljesítménybeli szűk keresztmetszeteket az éles rendszer előtt észleli.

Foglald össze ezt a bejegyzést a következőképpen: