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.

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.
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.

