Oracle PL/SQL BULK COLLECT: FORALL Näide

⚡ Nutikas kokkuvõte

HULLIKULT KOGUMINE Oracle PL/SQL hangib kollektsiooni korraga palju ridu, samas kui FORALL saadab hulgi DML-i tagasi andmebaasi. Mõlemad vähendavad kontekstivahetust SQL-i ja PL/SQL-mootorite vahel, suurendades jõudlust.

  • 📦 HULLIK KOGUMINE: Tõmbab mitu rida ühe korraga kollektsioonimuutujasse, asendades aeglase rida-realt toomise.
  • 🔁 KÕIGILE: Käivitab ühe INSERT, UPDATE või DELETE käsu kogu kollektsioonis ühe kontekstivahetusega.
  • 📏 LIMIT-klausel: Piirab iga BULK COLLECT funktsiooni poolt laetavate ridade arvu, kaitstes seansi mälu suurtes tabelites.
  • 📊 BULK COLLECTi atribuudid: Atribuut %BULK_ROWCOUNT(n) näitab, mitu rida n-s FORALL DML-lause mõjutas.
  • ⚙️ Nõutavad kogud: INTO-klausel peab olema suunatud kogumitüübile, näiteks pesastatud tabelile või assotsiatiivsele massiivile.
  • 🤖 AI abi: Tehisintellekti assistendid, näiteks GitHub Copilot, koostavad BULK COLLECT ja FORALL plokkide mustandi ning märgistavad puuduva LIMIT-klausli.

Oracle PL/SQL BULK COLLECT ja FORALL koos LIMIT-klausliga – ülevaade

Mis on BULK COLLECT?

BULK COLLECT vähendab kontekstivahetusi SQL ja PL/SQL-mootorit ning võimaldab SQL-mootoril kirjed korraga hankida.

Oracle PL / SQL pakub funktsionaalsust kirjete hulgi toomiseks, mitte ükshaaval toomiseks. Seda BULK COLLECT funktsiooni saab kasutada SELECT-lauses kirjete hulgi täitmiseks või... kursor hulgi. Kuna BULK COLLECT hangib kirjeid hulgi, peaks INTO-klausel alati sisaldama kogumitüübi muutujat. BULK COLLECTi peamine eelis on jõudluse suurendamine, vähendades andmebaasi ja PL/SQL-mootori vahelist interaktsiooni.

süntaksit:

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

Ülaltoodud süntaksis kasutatakse BULK COLLECTi andmete kogumiseks SELECT- ja FETCH-lausetest.

FORALL klausel

FORALL-lause täidab DML-i toimingud hulgiandmete puhul. See sarnaneb FOR-tsükli lausega, välja arvatud see, et FOR-tsüklis toimuvad toimingud kirje tasandil, samas kui FORALL-is puudub LOOP-kontseptsioon. Selle asemel töödeldakse kõiki antud vahemikus olevaid andmeid samaaegselt.

süntaksit:

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

<DML operations>;

Ülaltoodud süntaksis teostatakse antud DML-toiming kõigi andmete jaoks, mis asuvad alumise ja ülemise vahemiku vahel.

LIMIT klausel

Hulgikogumise kontseptsioon laadib kõik andmed sihtkogumi muutujasse hulgi, st kõik andmed täidetakse kogumi muutujasse korraga. Kuid see pole soovitatav, kui laaditavate kirjete koguarv on väga suur, sest kui PL/SQL proovib kõiki andmeid laadida, tarbib see rohkem seansimälu. Seega on alati hea selle hulgikogumise operatsiooni suurust piirata.

Selle suurusepiirangu saab hõlpsasti saavutada, kui SELECT-lauses lisada tingimus ROWNUM, kursori puhul aga see pole võimalik.

Selle ületamiseks Oracle on esitanud LIMIT-klausli, mis määrab hulgi hulka kuuluvate kirjete arvu.

süntaksit:

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

Ülaltoodud süntaksis kasutab kursori tõmbamise lause BULK COLLECT lauset koos LIMIT klausliga.

BULK COLLECT Atribuudid

Sarnaselt kursori atribuutidega on BULK COLLECT-il %BULK_ROWCOUNT(n), mis tagastab FORALL-lause n-ndas DML-lauses mõjutatud ridade arvu, st see annab FORALL-lauses mõjutatud kirjete arvu iga kollektsioonimuutuja väärtuse kohta. Termin 'n' näitab väärtuse järjestust kollektsioonis, mille jaoks ridade arvu on vaja.

Näide 1: Selles näites projitseerime kõik töötajate nimed emp-tabelist, kasutades funktsiooni BULK COLLECT, ja suurendame kõigi töötajate palka 5000 võrra, kasutades funktsiooni FORALL.

Allolev ekraanipilt näitab seda BULK COLLECT ja FORALL näidet koos selle väljundiga Oracle.

HULLIK KOGUMINE LIMIT ja FORALL näidetega töötaja palga uuendamine 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;
/

Väljund

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

Code Selgitus:

  • Code rida 2: Kursori guru99_det deklareerimine lause 'SELECT emp_name FROM emp' jaoks.
  • Code rida 3: Tabeli lv_emp_name_tbl deklareerimine VARCHAR2(50) tüübi tabelina.
  • Code rida 4: Lv_emp_name deklareerimine lv_emp_name_tbl tüübina.
  • Code rida 6: Kursori avamine.
  • Code rida 7: Kursori toomine käsuga BULK COLLECT, mille LIMIT suurus on 5000, muutujasse lv_emp_name.
  • Code rida 8-11: FOR-tsükli seadistamine kõigi kollektsiooni lv_emp_name kirjete printimiseks.
  • Code rida 12: FORALL-i kasutamine kõigi töötajate palkade värskendamiseks 5000 võrra.
  • Code rida 14: Pühendumine tehing.

KKK

Ei. BULK COLLECT SELECT ei anna kunagi NO_DATA_FOUND väärtust; selle asemel tagastab see tühja kogumi. Testige kogumikku alati enne .COUNT meetodiga.ping, vastasel juhul võite null rida vaikselt töödelda.

SAVE EXCEPTIONS lubab FORALL-il jätkata töötamist ka siis, kui üksikud read ebaõnnestuvad. Nurjunud read salvestatakse SQL%BULK_EXCEPTIONS-i ja seejärel Oracle tõstab ORA-24381, mille te lõksutate erand käitleja iga vea kontrollimiseks.

Kasutage BULK COLLECT funktsiooni alati, kui tsükkel loeb mitu rida. kursor FOR-tsükkel laadib iga lüliti kohta ühe rea, seega saab hulgilaadimine koos FORALL-iga suurte tulemuste komplektide puhul mitu korda kiiremini töötada.

BULK COLLECT tagastab korraga mitu rida, seega vajab see mitmerealist konteinerit. INTO sihtmärk peab olema kogumine näiteks pesastatud tabel, VARRAY või assotsiatiivne massiiv, mitte üksik skalaarmuutuja.

Ei. FORALL-päis käivitab täpselt ühe INSERT-, UPDATE-, DELETE- või MERGE-käsu. Ainult selle VALUES- ja WHERE-klauslite väärtused võivad iteratsiooni jooksul muutuda. Mitme lause puhul kasutage eraldi FORALL-lauseid.

Masstöötlus võib olla mitu korda kuni üle saja korra kiirem kui rida-realt kood, sest BULK COLLECT ja FORALL koondavad tuhandeid mootori kontekstilüliteid vähesteks, vähendades järsult suurte andmemahtude üldkulusid.

Jah. GitHubi koopia koostab kommentaarist BULK COLLECT käskude, FORALL DML-tsüklite ja LIMIT-klauslite mustandid ning pakub välja kogumitüübi deklaratsioone, kuigi peaksite ise üle vaatama partiide suurused ja veatöötluse.

Tehisintellekti assistendid skannivad tsükleid, mis laadivad või muudavad ühte rida korraga, ja soovitavad neid ümber kirjutada BULK COLLECT, LIMIT ja FORALL abil. See masinõppe ülevaade tuvastab puuduvad LIMIT piirangud ja jõudluse kitsaskohad enne tootmist.

Võta see postitus kokku järgmiselt: