Oracle PL/SQL BULK COLLECT: FORALL Exempel

โšก Smart sammanfattning

MASSUPHร„MTNING i Oracle PL/SQL hรคmtar mรฅnga rader samtidigt till en samling, medan FORALL skickar tillbaka bulk-DML till databasen. Bรฅda eliminerar kontextvรคxlingar mellan SQL- och PL/SQL-motorerna, vilket รถkar prestandan.

  • ๐Ÿ“ฆ MASSUPHร„MTNING: Hรคmtar flera rader i ett enda steg till en samlingsvariabel och ersรคtter lรฅngsam hรคmtning rad-fรถr-rad.
  • ๐Ÿ” Fร–R ALLA: Kรถr en INSERT, UPDATE eller DELETE รถver en hel samling med en enda kontextvรคxel.
  • ๐Ÿ“ LIMIT-klausul: Begrรคnsar hur mรฅnga rader varje BULK COLLECT hรคmtar lรคser in, vilket skyddar sessionsminnet pรฅ stora tabeller.
  • ๐Ÿ“Š Attribut fรถr BULK COLLECT: Attributet %BULK_ROWCOUNT(n) rapporterar hur mรฅnga rader den n:te FORALL DML-satsen pรฅverkade.
  • โš™๏ธ Obligatoriska samlingar: INTO-klausulen mรฅste rikta in sig pรฅ en samlingstyp, till exempel en kapslad tabell eller associativ array.
  • ๐Ÿค– AI-hjรคlp: AI-assistenter som GitHub Copilot utarbetar BULK COLLECT- och FORALL-block och flaggar en saknad LIMIT-klausul.

Oracle ร–versikt รถver PL/SQL BULK COLLECT och FORALL med LIMIT-klausul

Vad รคr BULK COLLECT?

MASSINSAMLING minskar kontextvรคxlingar mellan SQL och PL/SQL-motorn och lรฅter SQL-motorn hรคmta posterna samtidigt.

Oracle PL / SQL ger funktionen att hรคmta posterna i bulk istรคllet fรถr att hรคmta dem en i taget. Denna BULK COLLECT-sats kan anvรคndas i en SELECT-sats fรถr att fylla i posterna i bulk, eller fรถr att hรคmta en markรถren i bulk. Eftersom BULK COLLECT hรคmtar posterna i bulk, bรถr INTO-klausulen alltid innehรฅlla en variabel av samlingstypen. Den stรถrsta fรถrdelen med att anvรคnda BULK COLLECT รคr att det รถkar prestandan genom att minska interaktionen mellan databasen och PL/SQL-motorn.

Syntax:

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

I syntaxen ovan anvรคnds BULK COLLECT fรถr att samla in data frรฅn SELECT- och FETCH-satserna.

FORALL Klausul

FORALL-satsen utfรถr DML-operationer pรฅ data i bulk. Det liknar en FOR-loop-sats, fรถrutom att i en FOR-loop sker รฅtgรคrder pรฅ postnivรฅ, medan det i FORALL inte finns nรฅgot LOOP-koncept. Istรคllet bearbetas all data som finns i det givna omrรฅdet samtidigt.

Syntax:

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

<DML operations>;

I ovanstรฅende syntax kommer den givna DML-operationen att utfรถras fรถr all data som finns mellan det lรคgre och hรถgre intervallet.

LIMIT-klausul

Konceptet med bulkinsamling laddar all data i mรฅlinsamlingsvariabeln som en bulk, dvs. all data kommer att fyllas i insamlingsvariabeln pรฅ en gรฅng. Men detta รคr inte tillrรฅdligt nรคr det totala antalet poster som behรถver laddas รคr mycket stort, eftersom nรคr PL/SQL fรถrsรถker ladda all data fรถrbrukar det mer sessionsminne. Dรคrfรถr รคr det alltid bra att begrรคnsa storleken pรฅ denna bulkinsamlingsoperation.

Denna storleksgrรคns kan enkelt uppnรฅs genom att introducera ROWNUM-villkoret i SELECT-satsen, medan detta inte รคr mรถjligt fรถr en markรถr.

Fรถr att รถvervinna detta, Oracle har tillhandahรฅllit LIMIT-klausulen som definierar antalet poster som mรฅste inkluderas i bulkposten.

Syntax:

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

I syntaxen ovan anvรคnder `cursor fetch`-satsen `BULK COLLECT`-satsen tillsammans med `LIMIT`-klausulen.

BULK COLLECT-attribut

I likhet med markรถrattribut har BULK COLLECT %BULK_ROWCOUNT(n) som returnerar antalet rader som pรฅverkas i den n:te DML-satsen i FORALL-satsen, dvs. den ger antalet poster som pรฅverkas i FORALL-satsen fรถr varje enskilt vรคrde frรฅn samlingsvariabeln. Termen 'n' anger sekvensen av vรคrdet i samlingen fรถr vilket radantalet behรถvs.

Exempel 1: I det hรคr exemplet kommer vi att projicera alla anstรคlldas namn frรฅn anstรคllningstabellen med hjรคlp av BULK COLLECT, och vi kommer ocksรฅ att รถka lรถnen fรถr alla anstรคllda med 5000 med hjรคlp av FORALL.

Skรคrmdumpen nedan visar detta BULK COLLECT- och FORALL-exempel tillsammans med dess utdata i Oracle.

BULK COLLECT med LIMIT och FORALL exempel pรฅ uppdatering av anstรคlldas lรถn i 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;
/

Produktion

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

Code Fรถrklaring:

  • Code rad 2: Deklarerar markรถren guru99_det fรถr uttrycket 'SELECT anstรคlld_namn FROM anstรคlld'.
  • Code rad 3: Deklarerar lv_emp_name_tbl som en tabelltyp fรถr VARCHAR2(50).
  • Code rad 4: Deklarerar lv_emp_name som typen lv_emp_name_tbl.
  • Code rad 6: ร–ppnar markรถren.
  • Code rad 7: Hรคmtar markรถren med hjรคlp av BULK COLLECT med LIMIT-storleken 5000 till variabeln lv_emp_name.
  • Code rad 8-11: Konfigurerar en FOR-loop fรถr att skriva ut alla poster i samlingen lv_emp_name.
  • Code rad 12: Anvรคnd FORALL fรถr att uppdatera lรถnen fรถr alla anstรคllda med 5000.
  • Code rad 14: Att begรฅ transaktion.

Vanliga frรฅgor

Nej. En BULK COLLECT SELECT genererar aldrig NO_DATA_FOUND; istรคllet returnerar den en tom samling. Testa alltid samlingen med .COUNT-metoden innan du tittar.ping, annars kan du bearbeta noll rader tyst.

SAVE EXCEPTIONS lรฅter FORALL fortsรคtta kรถras รคven om enskilda rader misslyckas. Misslyckade rader lagras i SQL%BULK_EXCEPTIONS, och sedan Oracle hรถjer ORA-24381, som du fรฅngar i en undantag hanteraren fรถr att granska varje fel.

Anvรคnd BULK COLLECT nรคr en loop lรคser mรฅnga rader. markรถren FOR-loopen hรคmtar en rad per switch, sรฅ bulkhรคmtning plus FORALL kan kรถras mรฅnga gรฅnger snabbare pรฅ stora resultatmรคngder.

BULK COLLECT returnerar mรฅnga rader samtidigt, sรฅ den behรถver en container med flera rader. INTO-mรฅlet mรฅste vara ett samling sรฅsom en kapslad tabell, VARRAY eller associativ array, inte en enda skalรคr variabel.

Nej. En FORALL-header kรถr exakt en INSERT-, UPDATE-, DELETE- eller MERGE-sats. Endast vรคrdena i dess VALUES- och WHERE-klausuler kan รคndras per iteration. Fรถr flera satser, anvรคnd separata FORALL-satser.

Massbearbetning kan vara flera gรฅnger till รถver hundra gรฅnger snabbare รคn rad-fรถr-rad-kod, eftersom BULK COLLECT och FORALL komprimerar tusentals motorkontextvรคxlar till nรฅgra fรฅ, vilket kraftigt minskar kostnaden fรถr stora datavolymer.

Ja. GitHub Copilot utkastar BULK COLLECT-hรคmtningar, FORALL DML-loopar och LIMIT-klausuler frรฅn en kommentar, och fรถreslรฅr deklarationer av samlingstyper, รคven om du bรถr granska batchstorlekar och felhantering sjรคlv.

AI-assistenter skannar loopar som hรคmtar eller รคndrar en rad i taget och rekommenderar att de skrivs om med BULK COLLECT, LIMIT och FORALL. Denna maskininlรคrningsgranskning upptรคcker saknade LIMIT-grรคnser och prestandaflaskhalsar fรถre produktion.

Sammanfatta detta inlรคgg med: