Oracle PL/SQL BULK COLLECT: FORALL Exemplu

โšก Rezumat inteligent

COLECTARE รŽN VRAC รฎn Oracle PL/SQL preia mai multe rรขnduri simultan รฎntr-o colecศ›ie, รฎn timp ce FORALL รฎmpinge DML รฎn bloc รฎnapoi รฎn baza de date. Ambele eliminฤƒ comutarile de context รฎntre motoarele SQL ศ™i PL/SQL, crescรขnd performanศ›a.

  • ๐Ÿ“ฆ COLECTARE รŽN VRAC: Preia mai multe rรขnduri รฎntr-o singurฤƒ trecere รฎntr-o variabilฤƒ de colecศ›ie, รฎnlocuind preluarea lentฤƒ rรขnd cu rรขnd.
  • ๐Ÿ” PENTRU TOศšI: Ruleazฤƒ o singurฤƒ comandฤƒ INSERT, UPDATE sau DELETE รฎntr-o รฎntreagฤƒ colecศ›ie cu o singurฤƒ schimbare de context.
  • ๐Ÿ“ Clauza LIMIT: Limiteazฤƒ numฤƒrul de rรขnduri รฎncฤƒrcate de fiecare operaศ›iune BULK COLLECT fetch, protejรขnd memoria sesiunii pe tabelele mari.
  • ๐Ÿ“Š Atribute BULK COLLECT: Atributul %BULK_ROWCOUNT(n) raporteazฤƒ cรขte rรขnduri a afectat a n-a instrucศ›iune FORALL DML.
  • โš™๏ธ Colecศ›ii necesare: Clauza INTO trebuie sฤƒ vizeze un tip de colecศ›ie, cum ar fi un tabel imbricat sau o matrice asociativฤƒ.
  • ๐Ÿค– Asistenศ›ฤƒ AI: Asistenศ›ii AI, cum ar fi GitHub Copilot, redacteazฤƒ blocuri BULK COLLECT ศ™i FORALL ศ™i semnaleazฤƒ o clauzฤƒ LIMIT lipsฤƒ.

Oracle Prezentare generalฤƒ a clauzelor PL/SQL BULK COLLECT ศ™i FORALL cu LIMIT

Ce este BULK COLLECT?

BULK COLLECT reduce schimbฤƒrile de context รฎntre SQL ศ™i motorul PL/SQL ศ™i permite motorului SQL sฤƒ preia รฎnregistrฤƒrile simultan.

Oracle PL / SQL oferฤƒ funcศ›ionalitatea de preluare a รฎnregistrฤƒrilor รฎn bloc, รฎn loc de preluarea lor individualฤƒ. Aceastฤƒ instrucศ›iune BULK COLLECT poate fi utilizatฤƒ รฎntr-o instrucศ›iune SELECT pentru a popula รฎnregistrฤƒrile รฎn bloc sau pentru a prelua o cursor รฎn bloc. Deoarece BULK COLLECT preia รฎnregistrฤƒrile รฎn bloc, clauza INTO ar trebui sฤƒ conศ›inฤƒ รฎntotdeauna o variabilฤƒ de tip colecศ›ie. Principalul avantaj al utilizฤƒrii BULK COLLECT este cฤƒ creศ™te performanศ›a prin reducerea interacศ›iunii dintre baza de date ศ™i motorul PL/SQL.

Sintaxฤƒ:

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

รŽn sintaxa de mai sus, BULK COLLECT este utilizat pentru a colecta datele din instrucศ›iunile SELECT ศ™i FETCH.

Clauza FORALL

Instrucศ›iunea FORALL executฤƒ Operaศ›iuni DML pe date รฎn bloc. Seamฤƒnฤƒ cu o instrucศ›iune de buclฤƒ FOR, cu excepศ›ia faptului cฤƒ รฎntr-o buclฤƒ FOR acศ›iunile au loc la nivel de รฎnregistrare, รฎn timp ce รฎn FORALL nu existฤƒ conceptul de BUCLฤ‚. รŽn schimb, toate datele prezente รฎn intervalul dat sunt procesate รฎn acelaศ™i timp.

Sintaxฤƒ:

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

<DML operations>;

รŽn sintaxa de mai sus, operaศ›ia DML datฤƒ va fi executatฤƒ pentru toate datele prezente รฎntre intervalul inferior ศ™i cel superior.

Clauza LIMIT

Conceptul de colectare รฎn bloc รฎncarcฤƒ toate datele รฎn variabila de colectare ศ›intฤƒ ca o operaศ›iune รฎn bloc, adicฤƒ toate datele vor fi populate รฎn variabila de colectare dintr-o singurฤƒ datฤƒ. รŽnsฤƒ acest lucru nu este recomandabil atunci cรขnd numฤƒrul total de รฎnregistrฤƒri care trebuie รฎncฤƒrcate este foarte mare, deoarece atunci cรขnd PL/SQL รฎncearcฤƒ sฤƒ รฎncarce toate datele, consumฤƒ mai multฤƒ memorie de sesiune. Prin urmare, este รฎntotdeauna bine sฤƒ se limiteze dimensiunea acestei operaศ›iuni de colectare รฎn bloc.

Aceastฤƒ limitฤƒ de dimensiune poate fi uศ™or atinsฤƒ prin introducerea condiศ›iei ROWNUM รฎn instrucศ›iunea SELECT, รฎn timp ce รฎn cazul unui cursor acest lucru nu este posibil.

Pentru a depฤƒศ™i acest lucru, Oracle a furnizat clauza LIMIT care defineศ™te numฤƒrul de รฎnregistrฤƒri care trebuie incluse รฎn bloc.

Sintaxฤƒ:

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

รŽn sintaxa de mai sus, instrucศ›iunea fetch a cursorului utilizeazฤƒ instrucศ›iunea BULK COLLECT รฎmpreunฤƒ cu clauza LIMIT.

Atribute BULK COLLECT

Similar atributelor cursorului, BULK COLLECT are %BULK_ROWCOUNT(n) care returneazฤƒ numฤƒrul de rรขnduri afectate รฎn a n-a instrucศ›iune DML a instrucศ›iunii FORALL, adicฤƒ oferฤƒ numฤƒrul de รฎnregistrฤƒri afectate รฎn instrucศ›iunea FORALL pentru fiecare valoare din variabila colecศ›iei. Termenul โ€žnโ€ indicฤƒ secvenศ›a valorii din colecศ›ie pentru care este necesar numฤƒrul de rรขnduri.

Exemplu 1: รŽn acest exemplu, vom proiecta toate numele angajaศ›ilor din tabela emp folosind BULK COLLECT ศ™i vom creศ™te, de asemenea, salariul tuturor angajaศ›ilor cu 5000 folosind FORALL.

Captura de ecran de mai jos prezintฤƒ acest exemplu BULK COLLECT ศ™i FORALL รฎmpreunฤƒ cu rezultatul sฤƒu รฎn Oracle.

BULK COLLECT cu LIMIT ศ™i FORALL exemplu de actualizare a salariului angajatului รฎn 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;
/

producศ›ie

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

Code Explicaลฃie:

  • Code linia 2: Declararea cursorului guru99_det pentru instrucศ›iunea โ€žSELECT emp_name FROM empโ€.
  • Code linia 3: Se declarฤƒ lv_emp_name_tbl ca un tip de tabel de tip VARCHAR2(50).
  • Code linia 4: Declararea lui lv_emp_name ca fiind tipul lv_emp_name_tbl.
  • Code linia 6: Deschiderea cursorului.
  • Code linia 7: Preluarea cursorului folosind BULK COLLECT cu dimensiunea LIMIT de 5000 รฎn variabila lv_emp_name.
  • Code liniile 8-11: Configurarea unei bucle FOR pentru a afiศ™a toate รฎnregistrฤƒrile din colecศ›ia lv_emp_name.
  • Code linia 12: Se utilizeazฤƒ FORALL pentru a actualiza salariul tuturor angajaศ›ilor cu 5000.
  • Code linia 14: Angajarea tranzacศ›ie.

รŽntrebฤƒri frecvente

Nu. O comandฤƒ BULK COLLECT SELECT nu genereazฤƒ niciodatฤƒ NO_DATA_FOUND; รฎn schimb, returneazฤƒ o colecศ›ie goalฤƒ. Testaศ›i รฎntotdeauna colecศ›ia cu metoda .COUNT รฎnainte de a o testa.ping, altfel este posibil sฤƒ procesaศ›i zero rรขnduri รฎn tฤƒcere.

SAVE EXCEPTIONS permite ca FORALL sฤƒ continue sฤƒ ruleze atunci cรขnd rรขnduri individuale eศ™ueazฤƒ. Rรขndurile eศ™uate sunt stocate รฎn SQL%BULK_EXCEPTIONS, apoi Oracle genereazฤƒ ORA-24381, pe care รฎl prinzi รฎntr-un excepศ›ie tratator pentru a inspecta fiecare eroare.

Foloseศ™te BULK COLLECT ori de cรขte ori o buclฤƒ citeศ™te mai multe rรขnduri. cursor Bucla FOR preia un rรขnd per comutator, astfel รฎncรขt preluarea รฎn bloc plus FORALL poate rula de multe ori mai rapid pe seturi mari de rezultate.

BULK COLLECT returneazฤƒ mai multe rรขnduri simultan, deci are nevoie de un container cu mai multe rรขnduri. ศšinta INTO trebuie sฤƒ fie un colectare cum ar fi un tabel imbricat, VARRAY sau o matrice asociativฤƒ, nu o singurฤƒ variabilฤƒ scalarฤƒ.

Nu. Un antet FORALL executฤƒ exact o singurฤƒ comandฤƒ INSERT, UPDATE, DELETE sau MERGE. Doar valorile din clauzele sale VALUES ศ™i WHERE se pot modifica per iteraศ›ie. Pentru mai multe instrucศ›iuni, utilizaศ›i instrucศ›iuni FORALL separate.

Procesarea รฎn bloc poate fi de cรขteva ori pรขnฤƒ la peste o sutฤƒ de ori mai rapidฤƒ decรขt codul rรขnd cu rรขnd, deoarece BULK COLLECT ศ™i FORALL comprimฤƒ mii de comutatoare de context ale motorului รฎn cรขteva, reducรขnd drastic cheltuielile suplimentare pentru volumele mari de date.

Da. Copilotul GitHub schiศ›eazฤƒ fetch-urile BULK COLLECT, buclele FORALL DML ศ™i clauzele LIMIT dintr-un comentariu ศ™i sugereazฤƒ declaraศ›ii de tip de colecศ›ie, deศ™i ar trebui sฤƒ revizuiศ›i singur dimensiunile batch-urilor ศ™i gestionarea erorilor.

Asistenศ›ii inteligenศ›i artificiali scaneazฤƒ buclele care preiau sau modificฤƒ cรขte un rรขnd pe rรขnd ศ™i recomandฤƒ rescrierea lor cu BULK COLLECT, LIMIT ศ™i FORALL. Aceastฤƒ analizฤƒ a รฎnvฤƒศ›ฤƒrii automate identificฤƒ limitele LIMIT lipsฤƒ ศ™i blocajele de performanศ›ฤƒ รฎnainte de producศ›ie.

Rezumaศ›i aceastฤƒ postare cu: