Oracle PL/SQL BULK COLLECT: FORALL Exempel

Vad är BULK COLLECT?

BULK COLLECT minskar kontextväxlingarna mellan SQL och PL/SQL-motorn och tillåter SQL-motorn att hämta posterna på en gång.

Oracle PL/SQL tillhandahåller funktionen att hämta posterna i bulk istället för att hämta en efter en. Denna BULK COLLECT kan användas i 'SELECT'-satsen för att fylla i posterna i bulk eller för att hämta markören i bulk. Eftersom BULK COLLECT hämtar posten i BULK, bör INTO-satsen alltid innehålla en samlingsvariabel. 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 <columnl> BULK COLLECT INTO bulk_varaible FROM <table name>;
FETCH <cursor_name> BULK COLLECT INTO <bulk_varaible >;

I ovanstående syntax används BULK COLLECT för att samla in data från "SELECT" och "FETCH"-satsen.

FORALL Klausul

FORALL gör det möjligt att utföra DML-operationer på data i bulk. Det liknar det för FOR loop-satsen förutom i FÖR slinga saker händer på rekordnivå medan det i FORALL inte finns något LOOP-koncept. Istället bearbetas hela data som finns i det givna intervallet samtidigt.

Syntax:

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

<DML operations>;

I ovanstående syntax kommer den givna DML-operationen att exekveras för hela data som finns mellan lägre och högre intervall.

LIMIT-klausul

Massinsamlingskonceptet läser in hela data i målinsamlingsvariabeln som en bulk, dvs hela data kommer att fyllas i insamlingsvariabeln på en gång. Men detta är inte tillrådligt när den totala posten som behöver laddas är mycket stor, för när PL / SQL försöker ladda hela data det förbrukar mer sessionsminne. Därför är det alltid bra att begränsa storleken på denna bulkuppsamlingsoperation.

Denna storleksgräns kan dock enkelt uppnås genom att införa ROWNUM-villkoret i 'SELECT'-satsen, medan detta inte är möjligt för markören.

För att övervinna detta Oracle har tillhandahållit 'LIMIT'-klausul som definierar antalet poster som måste inkluderas i bulken.

Syntax:

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

I ovanstående syntax använder cursor fetch-satsen BULK COLLECT-satsen tillsammans med LIMIT-satsen.

BULK COLLECT-attribut

Liknar markören attributen BULK COLLECT har %BULK_ROWCOUNT(n) som returnerar antalet påverkade rader i nth DML-satsen för FORALL-satsen, dvs den kommer att ge antalet poster som påverkas i FORALL-satsen för varje enskilt värde från samlingsvariabeln. Termen 'n' indikerar värdesekvensen i samlingen, för vilken radräkningen behövs.

Exempelvis 1: I det här exemplet kommer vi att projicera alla anställdas namn från emp-tabellen med BULK COLLECT och vi kommer också att öka lönen för alla anställda med 5000 med FORALL.

BULK COLLECT-attribut

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 salaiy=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

Kodförklaring:

  • Kodrad 2: Deklarerar markören guru99_det för satsen 'SELECT emp_name FROM emp'.
  • Kodrad 3: Deklarerar lv_emp_name_tbl som tabelltyp för VARCHAR2(50)
  • Kodrad 4: Deklarerar lv_emp_name som lv_emp_name_tbl-typ.
  • Kodrad 6: Öppnar markören.
  • Kodrad 7: Hämta markören med BULK COLLECT med LIMIT-storleken som 5000 intl lv_emp_name-variabel.
  • Kodrad 8-11: Ställa in FOR-loop för att skriva ut alla poster i samlingen lv_emp_name.
  • Kodrad 12: Använder FORALL för att uppdatera lönen för alla anställda med 5000.
  • Kodrad 14: Begå transaktionen.