Oracle PL/SQL BULK COLLECT: FORALL Eksempel

Hva er BULK COLLECT?

BULK COLLECT reduserer kontekstbytte mellom SQL og PL/SQL-motor og lar SQL-motoren hente postene på en gang.

Oracle PL/SQL gir funksjonaliteten til å hente postene i bulk i stedet for å hente én etter én. Denne BULK COLLECT kan brukes i 'SELECT'-setningen for å fylle ut postene i bulk eller for å hente markøren i bulk. Siden BULK COLLECT henter posten i BULK, bør INTO-leddet alltid inneholde en samlingstypevariabel. Den største fordelen med å bruke BULK COLLECT er at det øker ytelsen ved å redusere interaksjonen mellom database og PL/SQL-motor.

Syntaks:

SELECT <columnl> BULK COLLECT INTO bulk_varaible FROM <table name>;
FETCH <cursor_name> BULK COLLECT INTO <bulk_varaible >;

I syntaksen ovenfor brukes BULK COLLECT for å samle inn data fra 'SELECT' og 'FETCH'-setningen.

FORALL klausul

FORALL gjør det mulig å utføre DML-operasjoner på data i bulk. Det ligner på FOR loop-setningen bortsett fra i FOR løkke ting skjer på rekordnivå, mens det i FORALL ikke er noe LOOP-konsept. I stedet blir hele dataen som er tilstede i det gitte området behandlet samtidig.

Syntaks:

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

<DML operations>;

I syntaksen ovenfor vil den gitte DML-operasjonen bli utført for hele dataen som er tilstede mellom lavere og høyere område.

LIMIT-klausul

Masseinnsamlingskonseptet laster hele dataen inn i målinnsamlingsvariabelen som en bulk, dvs. at hele dataen vil fylles inn i innsamlingsvariabelen på én gang. Men dette er ikke tilrådelig når den totale posten som må lastes er veldig stor, fordi når PL / SQL prøver å laste inn hele dataen, det bruker mer øktminne. Derfor er det alltid greit å begrense størrelsen på denne bulkoppsamlingsoperasjonen.

Imidlertid kan denne størrelsesgrensen enkelt oppnås ved å introdusere ROWNUM-betingelsen i 'SELECT'-setningen, mens dette ikke er mulig for markøren.

For å overvinne dette Oracle har gitt 'LIMIT'-klausul som definerer antall poster som må inkluderes i massen.

Syntaks:

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

I syntaksen ovenfor bruker cursor fetch-setningen BULK COLLECT-setningen sammen med LIMIT-leddet.

BULK COLLECT-attributter

Lik markør attributter BULK COLLECT har %BULK_ROWCOUNT(n) som returnerer antall berørte rader i nth DML-setning av FORALL-setningen, dvs. den vil gi antallet poster som er berørt i FORALL-setningen for hver enkelt verdi fra samlingsvariabelen. Begrepet 'n' angir verdisekvensen i samlingen som radtellingen er nødvendig for.

Eksempel 1: I dette eksemplet vil vi projisere alle ansattes navn fra emp-tabellen ved å bruke BULK COLLECT, og vi skal også øke lønnen til alle ansatte med 5000 ved å bruke FORALL.

BULK COLLECT-attributter

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

Produksjon

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

Kodeforklaring:

  • Kodelinje 2: Erklærer markøren guru99_det for setningen 'SELECT emp_name FROM emp'.
  • Kodelinje 3: Erklærer lv_emp_name_tbl som tabelltype for VARCHAR2(50)
  • Kodelinje 4: Erklærer lv_emp_name som lv_emp_name_tbl type.
  • Kodelinje 6: Åpne markøren.
  • Kodelinje 7: Henter markøren ved å bruke BULK COLLECT med LIMIT-størrelsen som 5000 intl lv_emp_name-variabel.
  • Kodelinje 8-11: Sette opp FOR loop for å skrive ut all posten i samlingen lv_emp_name.
  • Kodelinje 12: Ved å bruke FORALL oppdaterer lønnen til alle ansatte med 5000.
  • Kodelinje 14: Forplikter transaksjonen.