Oracle PL/SQL-markør: Implicit, Eksplicit, Til Loop med Eksempel

⚡ Smart opsummering

Markører i Oracle PL/SQL er pointere til det kontekstområde, der indeholder de rækker, der returneres af en SQL-sætning. Der findes to typer: implicitte cursorer, der oprettes automatisk til DML, og eksplicitte cursorer, der deklareres og styres af programmøren.

  • 📍 Kontekstområde: En markør peger på det kontekstområde, der gemmer en SQL-sætning og dens returnerede aktive sæt.
  • 🇧🇷 Implicit markør: Oracle åbner automatisk en implicit markør for hver DML-sætning og SELECT INTO med én række.
  • Eksplicit markør: En programmør erklærer, åbner, henter og lukker en eksplicit markør for at opnå fuld kontrol.
  • 🔎 Markørattributter: %FOUND, %NOTFOUND, %ISOPEN og %ROWCOUNT rapporterer status for den seneste handling.
  • 🔁 Markør FOR-løkke: En FOR-løkke åbner, henter og lukker en markør implicit uden behov for manuelle trin.
  • 🤖 AI Assistance: AI-assistenter som f.eks. GitHub Copilot udkast til markørløkker og flag ikke-lukkede markører.

Oracle PL/SQL-markør, implicit eksplicit og FOR-løkke

Hvad er CURSOR i PL/SQL?

En markør er en peger på kontekstområdet. Oracle opretter et kontekstområde til behandling af en SQL erklæring, og dette område indeholder alle oplysninger om erklæringen.

PL / SQL tillader programmøren at styre kontekstområdet via markøren. En markør indeholder de rækker, der returneres af SQL-sætningen, og det sæt af rækker, som markøren indeholder, kaldes det aktive sæt. Disse markører kan også navngives, så de kan refereres til fra et andet sted i koden.

Markøren er af to typer:

  • Implicit markør
  • Eksplicit markør

Implicit markør

Når som helst DML-operation sker i databasen, oprettes en implicit cursor, der indeholder de rækker, der er berørt af den pågældende operation. Disse cursorer kan ikke navngives, og derfor kan de ikke styres eller henvises til fra et andet sted i koden. Vi kan kun referere til den seneste cursor via cursorattributterne.

Eksplicit markør

Programmører har lov til at oprette et navngivet kontekstområde til at udføre deres DML-operationer og få mere kontrol over det. Den eksplicitte markør skal defineres i deklarationsafsnittet af PL/SQL-blok, og den er oprettet til den SELECT-sætning, der skal bruges i koden.

Nedenfor er trinnene involveret i at arbejde med eksplicitte markører:

  • Deklarering af markøren: At deklarere markøren betyder simpelthen at oprette et navngivet kontekstområde til SELECT-sætningen, der er defineret i deklarationsdelen. Navnet på dette kontekstområde er det samme som markørnavnet.
  • Åbning af markøren: Når markøren åbnes, instrueres PL/SQL til at allokere hukommelsen til denne markør. Det gør markøren klar til at hente posterne.
  • Henter data fra markøren: I denne proces udføres SELECT-sætningen, og de hentede rækker gemmes i den allokerede hukommelse. Disse kaldes nu aktive sæt. Hentning af data fra markøren er en aktivitet på record-niveau, hvilket betyder, at vi kan tilgå dataene record-for-record. Hver fetch-sætning henter ét aktivt sæt og indeholder informationen fra den pågældende record. Denne sætning er den samme som en SELECT-sætning, der henter recorden og tildeler den til variablen i INTO-klausulen, men den vil ikke kaste nogen undtagelser.
  • Lukning af markøren: Når alle poster er hentet, skal vi lukke markøren, så den hukommelse, der er allokeret til dette kontekstområde, frigives.

Syntaks

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

I ovenstående syntaks indeholder deklarationsdelen deklarationen af ​​cursoren og den cursorvariabel, som de hentede data vil blive tildelt. Cursoren oprettes for SELECT-sætningen, der er angivet i cursordeklarationen. I udførelsesdelen åbnes, hentes og lukkes den deklarerede cursor.

Markørattributter

Både den implicitte og den eksplicitte markør har bestemte attributter, der kan tilgås. Disse attributter giver mere information om markørens operationer. Nedenfor er de forskellige markørattributter og deres anvendelse.

Markørattribut Beskrivelse
% FUNDET Returnerer det booleske resultat SAND, hvis den seneste henteoperation hentede en post; ellers returneres FALSK.
%IKKE FUNDET Fungerer modsat %FOUND. Den returnerer TRUE, hvis den seneste henteoperation ikke kunne hente nogen poster.
%ER ÅBEN Returnerer det booleske resultat SAND, hvis den givne markør allerede er åben; ellers returneres FALSK.
% ROWCOUNT Returnerer en numerisk værdi, der angiver det faktiske antal poster, der er påvirket eller hentet af handlingen.

Eksempel på eksplicit markør: I dette eksempel vil vi se, hvordan man deklarerer, åbner, henter og lukker en eksplicit cursor. Vi vil projicere alle medarbejdernavnene fra emp-tabellen ved hjælp af en cursor. Vi vil også bruge en cursor-attribut til at indstille løkken til at hente alle poster fra cursoren.

Skærmbilledet nedenfor viser dette eksplicitte markøreksempel og dets output i Oracle.

Eksplicit cursoreksempel, der henter medarbejdernavne fra emp-tabellen i 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;
/

Produktion

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

Code Forklaring

  • Code linje 2: Deklarerer markøren guru99_det for sætningen 'SELECT emp_name FROM emp'.
  • Code linje 3: Deklarering af variablen lv_emp_name med %type forankret til emp.emp_name.
  • Code linje 5: Åbner markøren guru99_det.
  • Code linje 6: Indstilling af den grundlæggende løkkesætning til at hente alle poster i emp-tabellen.
  • Code linje 7: Henter guru99_det-dataene og tildeler værdien til lv_emp_name.
  • Code linje 8: Brug af cursorattributten %NOTFOUND til at kontrollere, om alle poster i cursoren er hentet. Hvis hentet, returneres TRUE, og control afslutter løkken; ellers fortsætter control med at hente dataene fra cursoren og udskriver dem.
  • Code linje 10: EXIT-betingelse for loop-sætningen.
  • Code linje 12: Udskriv det hentede medarbejdernavn.
  • Code linje 14: Brug markørattributten %ROWCOUNT til at finde det samlede antal poster, der er hentet af markøren.
  • Code linje 15: Efter at have afsluttet løkken lukkes markøren, og den allokerede hukommelse frigøres.

FOR Loop Cursor-erklæring

En markør FOR sløjfe kan bruges til at arbejde med cursorer. Vi kan give cursorens navn i stedet for en intervalgrænse i FOR-løkken, så løkken arbejder fra cursorens første record til cursorens sidste record. Cursorvariablen, åbning af cursoren, hentning og lukning af cursoren udføres alle implicit af FOR-løkken.

Syntaks

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

I ovenstående syntaks indeholder deklarationsdelen deklarationen af ​​cursoren. Cursoren oprettes for den SELECT-sætning, der er angivet i cursordeklarationen. I udførelsesdelen sættes den deklarerede cursor op i FOR-løkken, og løkkevariablen 'I' opfører sig som cursorvariabel i dette tilfælde.

Oracle Eksempel på markør til løkke: I dette eksempel vil vi projicere alle medarbejdernavnene fra emp-tabellen ved hjælp af en cursor-FOR-løkke.

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

Produktion

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

Code Forklaring

  • Code linje 2: Deklarerer markøren guru99_det for sætningen 'SELECT emp_name FROM emp'.
  • Code linje 4: Konstruktion af FOR-løkken for markøren med løkkevariablen lv_emp_name.
  • Code linje 6: Udskrivning af medarbejdernavnet i hver iteration af løkken.
  • Code linje 7: Afslut løkken (SLUT LOOP).

Bemærk: I en cursor-FOR-løkke kan cursorattributter ikke bruges, da åbning, hentning og lukning af cursoren sker implicit af FOR-løkken.

Ofte Stillede Spørgsmål

En REF CURSOR (markørvariabel) er en pointer til et resultatsæt for en forespørgsel. I modsætning til en statisk markør kan den åbne forskellige forespørgsler under kørsel og sende resultater mellem PL/SQL-blokke eller til klientprogrammer.

En normal markør henter én række pr. HENTCH, hvilket forårsager mange kontekstskift. MASSEINDSAMLING indlæser mange rækker i en samling i en enkelt hentning, hvilket reducerer overhead markant på store resultatsæt.

Ja. Deklarer en parameteriseret cursor såsom CURSOR c(dept NUMBER) IS SELECT …, og send derefter værdier ved OPEN c(10). Parametre giver dig mulighed for at genbruge én cursordefinition med forskellige filterværdier.

FOR UPDATE låser de rækker, som en markør vælger, så ingen andre kan ændre dem. WHERE CURRENT OF opdaterer eller sletter derefter den præcise række, der lige er hentet, uden at gentage WHERE-betingelsen.

Åbne markører bevarer deres hukommelse reserveret og tæller med i OPEN_CURSORS-grænsen. Hvis mange åbne markører efterlades, hæves ORA-01000: det maksimale antal åbne markører er overskredet, så LUK altid en eksplicit markør efter brug.

Hver FETCH skifter mellem PL/SQL- og SQL-motorerne. Tusindvis af sådanne kontekstskift akkumuleres, så en enkelt sætbaseret SQL-sætning eller BULK COLLECT behandler normalt de samme rækker langt hurtigere.

Ja. GitHub Copilot udarbejder eksplicitte OPEN-, FETCH- og CLOSE-løkker eller markør-FOR-løkker fra en kommentar, tilføjer %NOTFOUND exit-kontroller og foreslår attributnavne, selvom du bør gennemgå logikken først.

AI-assistenter markerer række-for-række cursorløkker, der kan blive sætbaseret SQL eller BULK COLLECT, finder ikke-lukkede cursorer og forklarer %attribut-adfærd. Denne maskinlæringsgennemgang forbedrer ydeevnen, før koden når produktion.

Opsummer dette indlæg med: