Oracle Cursor PL/SQL: implicit, explicit, buclă For cu exemplu

⚡ Rezumat inteligent

Cursoare în Oracle PL/SQL sunt pointeri către zona de context care conține rândurile returnate de o instrucțiune SQL. Există două tipuri: cursori impliciți, creați automat pentru DML, și cursori expliciți, declarați și controlați de programator.

  • 📍 Zona de context: Un cursor indică zona de context care stochează o instrucțiune SQL și setul activ returnat.
  • ⚙️ Cursor implicit: Oracle deschide automat un cursor implicit pentru fiecare instrucțiune DML și pentru comanda SELECT INTO pe un singur rând.
  • Cursor explicit: Un programator declară, deschide, preia și închide un cursor explicit pentru control complet.
  • 🔎 Atributele cursorului: %FOUND, %NOTFOUND, %ISOPEN și %ROWCOUNT raportează starea celei mai recente operații.
  • 🔁 Bucla FOR a cursorului: O buclă FOR deschide, preia și închide implicit un cursor, fără a fi nevoie de pași manuali.
  • 🤖 Asistență AI: Asistenții AI, cum ar fi GitHub Copilot, schițează bucle de cursor și semnalizează cursoarele neînchise.

Oracle Cursor PL/SQL Implicit Explicit și Bucla FOR

Ce este CURSOR în PL/SQL?

Un cursor este un pointer către zona de context. Oracle creează o zonă de context pentru procesarea unui SQL declarație, iar această zonă conține toate informațiile despre declarație.

PL / SQL permite programatorului să controleze zona de context prin intermediul cursorului. Un cursor conține rândurile returnate de instrucțiunea SQL, iar setul de rânduri pe care îl conține cursorul este denumit set activ. Aceste cursoare pot fi, de asemenea, denumite astfel încât să poată fi accesate din alt loc din cod.

Cursorul este de două tipuri:

  • Cursor implicit
  • Cursor explicit

Cursor implicit

Ori de câte ori Operațiune DML Dacă apare o eroare în baza de date, se creează un cursor implicit care conține rândurile afectate de operațiunea respectivă. Acești cursori nu pot fi denumiți și, prin urmare, nu pot fi controlați sau la care se poate face referire din altă parte a codului. Putem face referire doar la cel mai recent cursor prin intermediul atributelor cursorului.

Cursor explicit

Programatorilor li se permite să creeze o zonă de context denumită pentru a executa operațiunile DML și a obține mai mult control asupra acesteia. Cursorul explicit ar trebui definit în secțiunea de declarație a bloc PL/SQLși este creat pentru instrucțiunea SELECT care trebuie utilizată în cod.

Mai jos sunt pașii implicați în lucrul cu cursori expliciți:

  • Declararea cursorului: Declararea cursorului înseamnă pur și simplu crearea unei zone de context denumite pentru instrucțiunea SELECT, definită în partea de declarație. Numele acestei zone de context este același cu numele cursorului.
  • Deschiderea cursorului: Deschiderea cursorului instruiește PL/SQL să aloce memorie pentru acest cursor. Aceasta pregătește cursorul pentru preluarea înregistrărilor.
  • Preluarea datelor de la cursor: În acest proces, instrucțiunea SELECT este executată, iar rândurile preluate sunt stocate în memoria alocată. Acestea sunt acum numite seturi active. Preluarea datelor de la cursor este o activitate la nivel de înregistrare, ceea ce înseamnă că putem accesa datele înregistrare cu înregistrare. Fiecare instrucțiune fetch preia un set activ și păstrează informațiile despre înregistrarea respectivă. Această instrucțiune este aceeași cu o instrucțiune SELECT care preia înregistrarea și o atribuie variabilei din clauza INTO, dar nu va genera nicio eroare. excepții.
  • Închiderea cursorului: Odată ce toate înregistrările sunt preluate, trebuie să închidem cursorul astfel încât memoria alocată acestei zone de context să fie eliberată.

Sintaxă

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
<cursor_variable declaration>;
BEGIN
OPEN <cursor_name>;
FETCH <cursor_name> INTO <cursor_variable>;
.
.
CLOSE <cursor_name>;
END;

În sintaxa de mai sus, partea de declarație conține declarația cursorului și a variabilei cursor în care vor fi atribuite datele preluate. Cursorul este creat pentru instrucțiunea SELECT dată în declarația cursorului. În partea de execuție, cursorul declarat este deschis, preluat și închis.

Atributele cursorului

Atât cursorul implicit, cât și cursorul explicit au anumite atribute care pot fi accesate. Aceste atribute oferă mai multe informații despre operațiunile cursorului. Mai jos sunt prezentate diferitele atribute ale cursorului și utilizarea lor.

Atributul cursorului Descriere
%GĂSITE Returnează rezultatul boolean TRUE dacă cea mai recentă operațiune de preluare a preluat o înregistrare cu succes; în caz contrar, returnează FALSE.
%NU A FOST GĂSIT Funcționează opusul lui %FOUND. Returnează TRUE dacă cea mai recentă operațiune de preluare nu a putut prelua nicio înregistrare.
%ESTE DESCHIS Returnează rezultatul boolean TRUE dacă cursorul dat este deja deschis; în caz contrar, returnează FALSE.
%ROWCOUNT Returnează o valoare numerică care indică numărul real de înregistrări afectate sau preluate de operație.

Exemplu de cursor explicit: În acest exemplu, vom vedea cum se declară, se deschide, se preia și se închide un cursor explicit. Vom proiecta toate numele angajaților din tabela emp folosind un cursor. De asemenea, vom folosi un atribut cursor pentru a seta bucla pentru a prelua toate înregistrările de la cursor.

Captura de ecran de mai jos prezintă acest exemplu explicit de cursor și rezultatul său în Oracle.

Exemplu de cursor explicit care preia numele angajaților din tabelul emp din Oracle PL / SQL

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
lv_emp_name emp.emp_name%type;
BEGIN
OPEN guru99_det;
LOOP
FETCH guru99_det INTO lv_emp_name;
IF guru99_det%NOTFOUND
THEN
EXIT;
END IF;
Dbms_output.put_line('Employee Fetched:'||lv_emp_name);
END LOOP;
Dbms_output.put_line('Total rows fetched is'||guru99_det%ROWCOUNT);
CLOSE guru99_det;
END;
/

producție

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Total rows fetched is 3

Code Explicație

  • Code linia 2: Declararea cursorului guru99_det pentru instrucțiunea „SELECT emp_name FROM emp”.
  • Code linia 3: Declararea variabilei lv_emp_name cu %tip ancorat la emp.emp_name.
  • Code linia 5: Deschiderea cursorului guru99_det.
  • Code linia 6: Setarea instrucțiunii de buclă de bază pentru a prelua toate înregistrările din tabelul emp.
  • Code linia 7: Preia datele guru99_det și atribuie valoarea lui lv_emp_name.
  • Code linia 8: Se utilizează atributul cursor %NOTFOUND pentru a verifica dacă toate înregistrările din cursor sunt preluate. Dacă este preluat, returnează TRUE și controlul iese din buclă; altfel, controlul continuă să preia datele de la cursor și le afișează.
  • Code linia 10: Condiție EXIT pentru instrucțiunea buclă.
  • Code linia 12: Tipăriți numele angajatului preluat.
  • Code linia 14: Folosind atributul cursor %ROWCOUNT pentru a găsi numărul total de înregistrări preluate de cursor.
  • Code linia 15: După ieșirea din buclă, cursorul se închide și memoria alocată este eliberată.

FOR Loop Cursor instrucțiune

Un cursor bucla FOR poate fi folosit pentru lucrul cu cursori. Putem da numele cursorului în loc de o limită de interval în instrucțiunea buclei FOR, astfel încât bucla să funcționeze de la prima înregistrare a cursorului până la ultima înregistrare a cursorului. Variabila cursor, deschiderea cursorului, preluarea și închiderea cursorului sunt toate făcute implicit de bucla FOR.

Sintaxă

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
BEGIN
FOR I IN <cursor_name>
LOOP
.
.
END LOOP;
END;

În sintaxa de mai sus, partea de declarație conține declarația cursorului. Cursorul este creat pentru instrucțiunea SELECT dată în declarația cursorului. În partea de execuție, cursorul declarat este configurat în bucla FOR, iar variabila buclei „I” se comportă ca variabilă cursor în acest caz.

Oracle Cursor pentru exemplu de buclă: În acest exemplu, vom proiecta toate numele angajaților din tabela emp folosind o buclă FOR cu cursor.

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
BEGIN
FOR lv_emp_name IN guru99_det
LOOP
Dbms_output.put_line('Employee Fetched:'||lv_emp_name.emp_name);
END LOOP;
END;
/

producție

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY

Code Explicație

  • Code linia 2: Declararea cursorului guru99_det pentru instrucțiunea „SELECT emp_name FROM emp”.
  • Code linia 4: Construirea buclei FOR pentru cursor cu variabila de buclă lv_emp_name.
  • Code linia 6: Tipărirea numelui angajatului în fiecare iterație a buclei.
  • Code linia 7: Ieșire din buclă (END LOOP).

Notă: Într-o buclă FOR-cursor, atributele cursorului nu pot fi utilizate, deoarece deschiderea, preluarea și închiderea cursorului se fac implicit de către bucla FOR.

Întrebări frecvente

Un REF CURSOR (variabilă cursor) este un pointer către un set de rezultate ale unei interogări. Spre deosebire de un cursor static, acesta poate deschide diferite interogări în timpul execuției și poate transmite rezultate între blocuri PL/SQL sau către programele client.

Un cursor normal preia un rând per FETCH, provocând numeroase schimbări de context. COLECTARE VRAC încarcă mai multe rânduri într-o colecție într-o singură preluare, reducând drastic costurile pentru seturile mari de rezultate.

Da. Declarați un cursor parametrizat, cum ar fi CURSOR c(dept NUMBER) IS SELECT …, apoi transmiteți valorile la OPEN c(10). Parametrii vă permit să reutilizați o definiție a cursorului cu valori de filtru diferite.

FOR UPDATE blochează rândurile selectate de cursor, astfel încât nimeni altcineva să le poată modifica. WHERE CURRENT OF actualizează sau șterge apoi exact rândul tocmai preluat, fără a repeta condiția WHERE.

Cursoarele deschise își păstrează memoria rezervată și se calculează în limita OPEN_CURSORS. Dacă se lasă multe cursoare deschise, se generează în cele din urmă eroarea ORA-01000: numărul maxim de cursoare deschise a fost depășit, așa că întotdeauna ÎNCHIDEȚI un cursor explicit după utilizare.

Fiecare comandă FETCH comută între motoarele PL/SQL și SQL. Mii de astfel de schimbări de context se adună, astfel încât o singură instrucțiune SQL bazată pe seturi sau BULK COLLECT procesează de obicei aceleași rânduri mult mai rapid.

Da. Copilotul GitHub elimină buclele explicite OPEN, FETCH și CLOSE sau buclele FOR ale cursorului dintr-un comentariu, adaugă verificări de ieșire %NOTFOUND și sugerează nume de atribute, deși ar trebui să revizuiți mai întâi logica.

Asistenții inteligenți artificiali semnalizează buclele de cursor rând cu rând care ar putea deveni SQL bazate pe seturi sau BULK COLLECT, identifică cursorii neînchiși și explică comportamentul atributelor %. Această analiză a învățării automate îmbunătățește performanța înainte ca codul să ajungă în producție.

Rezumați această postare cu: