Oracle PL/SQL kursor: implicitno, eksplicitno, for petlja s primjerom

⚡ Pametni sažetak

Kursori u Oracle PL/SQL su pokazivači na kontekstno područje koje sadrži retke vraćene SQL naredbom. Postoje dvije vrste: implicitni kursori, automatski kreirani za DML, i eksplicitni kursori, deklarirani i kontrolirani od strane programera.

  • ???? Područje konteksta: Kursor pokazuje na kontekstno područje koje pohranjuje SQL naredbu i njen vraćeni aktivni skup.
  • Implicitni kursor: Oracle automatski otvara implicitni kursor za svaku DML naredbu i jednoredni SELECT INTO.
  • Eksplicitni kursor: Programer deklarira, otvara, dohvaća i zatvara eksplicitni kursor za potpunu kontrolu.
  • 🔎 Atributi kursora: %FOUND, %NOTFOUND, %ISOPEN i %ROWCOUNT izvještavaju o statusu najnovije operacije.
  • 🔁 Kursor FOR petlja: FOR petlja implicitno otvara, dohvaća i zatvara kursor, bez potrebe za ručnim koracima.
  • 🤖 AI pomoć: AI asistenti poput GitHub Copilota izrađuju petlje kursora za izradu nacrta i označavaju nezatvorene kursore.

Oracle PL/SQL kursor Implicitni Eksplicitni i FOR petlja

Što je CURSOR u PL/SQL?

Kursor je pokazivač na kontekstno područje. Oracle stvara kontekstno područje za obradu SQL izjava, a ovo područje sadrži sve informacije o izjavi.

PL / SQL omogućuje programeru kontrolu kontekstnog područja putem kursora. Kursor sadrži retke koje vraća SQL naredba, a skup redaka koje kursor sadrži naziva se aktivni skup. Ovi kursori također se mogu imenovati tako da se na njih može pozivati ​​s drugog mjesta u kodu.

Kursor je dvije vrste:

  • Implicitni kursor
  • Eksplicitni kursor

Implicitni kursor

Kad god bilo DML operacija događa u bazi podataka, stvara se implicitni kursor koji sadrži retke na koje utječe ta određena operacija. Ove kursore nije moguće imenovati i stoga ih nije moguće kontrolirati ili na njih pozivati ​​s drugog mjesta u kodu. Pomoću atributa kursora možemo se pozivati ​​samo na najnoviji kursor.

Eksplicitni kursor

Programerima je dopušteno stvaranje imenovanog kontekstnog područja za izvršavanje svojih DML operacija i dobivanje veće kontrole nad njim. Eksplicitni kursor treba biti definiran u odjeljku deklaracije PL/SQL blok, a kreiran je za SELECT naredbu koja se treba koristiti u kodu.

U nastavku su navedeni koraci za rad s eksplicitnim kursorima:

  • Deklarisanje kursora: Deklarisanje kursora jednostavno znači stvaranje jednog imenovanog kontekstnog područja za SELECT naredbu koja je definirana u dijelu deklaracije. Naziv ovog kontekstnog područja isti je kao i naziv kursora.
  • Otvaranje kursora: Otvaranjem kursora daje se uputa PL/SQL-u da dodijeli memoriju za ovaj kursor. To priprema kursor za dohvaćanje zapisa.
  • Dohvaćanje podataka iz kursora: U ovom procesu, naredba SELECT se izvršava i dohvaćeni retci se pohranjuju u dodijeljenu memoriju. Oni se sada nazivaju aktivni skupovi. Dohvaćanje podataka iz kursora je aktivnost na razini zapisa, što znači da podacima možemo pristupiti zapis po zapis. Svaka naredba dohvaća jedan aktivni skup i sadrži informacije o tom određenom zapisu. Ova naredba je ista kao i naredba SELECT koja dohvaća zapis i dodjeljuje ga varijabli u INTO klauzuli, ali neće izbaciti nijedan iznimke.
  • Zatvaranje kursora: Nakon što su svi zapisi dohvaćeni, moramo zatvoriti kursor kako bi se oslobodila memorija dodijeljena ovom kontekstualnom području.

Sintaksa

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

U gornjoj sintaksi, dio deklaracije sadrži deklaraciju kursora i varijablu kursora u koju će se dodijeliti dohvaćeni podaci. Kursor se stvara za SELECT naredbu koja je navedena u deklaraciji kursora. U dijelu izvršenja, deklarirani kursor se otvara, dohvaća i zatvara.

Atributi kursora

I implicitni i eksplicitni kursor imaju određene atribute kojima se može pristupiti. Ti atributi daju više informacija o operacijama kursora. U nastavku su navedeni različiti atributi kursora i njihova upotreba.

Atribut kursora Description
%PRONAĐENO Vraća logičku vrijednost TRUE ako je najnovija operacija dohvaćanja uspješno dohvatila zapis; inače vraća FALSE.
%NIJE PRONAĐENO Radi suprotno od %FOUND. Vraća TRUE ako najnovija operacija dohvaćanja nije mogla dohvatiti nijedan zapis.
%OTVORENO JE Vraća logičku vrijednost TRUE ako je zadani kursor već otvoren; u suprotnom vraća FALSE.
%ROWCOUNT Vraća numeričku vrijednost koja daje stvarni broj zapisa na koje je operacija utjecala ili koje je dohvatila.

Primjer eksplicitnog kursora: U ovom primjeru vidjet ćemo kako deklarirati, otvoriti, dohvatiti i zatvoriti eksplicitni kursor. Projicirat ćemo sva imena zaposlenika iz emp tablice pomoću kursora. Također ćemo koristiti atribut kursora za postavljanje petlje za dohvaćanje svih zapisa iz kursora.

Snimka zaslona u nastavku prikazuje ovaj primjer eksplicitnog kursora i njegov izlaz u Oracle.

Primjer eksplicitnog kursora koji dohvaća imena zaposlenika iz emp tablice u 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;
/

Izlaz

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

Code Objašnjenje

  • Code redak 2: Deklarisanje kursora guru99_det za naredbu 'SELECT emp_name FROM emp'.
  • Code redak 3: Deklarisanje varijable lv_emp_name s %tip usidreno na emp.emp_name.
  • Code redak 5: Otvaranje kursora guru99_det.
  • Code redak 6: Postavljanje osnovne naredbe petlje za dohvaćanje svih zapisa u emp tablici.
  • Code redak 7: Dohvaća podatke guru99_det i dodjeljuje vrijednost lv_emp_name.
  • Code redak 8: Korištenje atributa kursora %NOTFOUND za provjeru jesu li svi zapisi u kursoru dohvaćeni. Ako jesu, vraća TRUE i kontrola izlazi iz petlje; inače kontrola nastavlja dohvaćati podatke iz kursora i ispisuje ih.
  • Code redak 10: EXIT uvjet za naredbu petlje.
  • Code redak 12: Ispišite dohvaćeno ime zaposlenika.
  • Code redak 14: Korištenje atributa kursora %ROWCOUNT za pronalaženje ukupnog broja zapisa koje je kursor dohvatio.
  • Code redak 15: Nakon izlaska iz petlje, kursor se zatvara i alocirana memorija se oslobađa.

FOR Loop Cursor izjava

Kursor FOR petlja može se koristiti za rad s kursorima. U naredbi FOR petlje možemo dati naziv kursora umjesto ograničenja raspona, tako da petlja radi od prvog zapisa kursora do posljednjeg zapisa kursora. Varijabla kursora, otvaranje kursora, dohvaćanje i zatvaranje kursora implicitno se obavljaju u FOR petlji.

Sintaksa

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

U gornjoj sintaksi, dio deklaracije sadrži deklaraciju kursora. Kursor se stvara za SELECT naredbu koja je navedena u deklaraciji kursora. U dijelu izvršenja, deklarirani kursor se postavlja u FOR petlju, a varijabla petlje 'I' se u ovom slučaju ponaša kao varijabla kursora.

Oracle Primjer kursora za petlju: U ovom primjeru, projicirat ćemo sva imena zaposlenika iz emp tablice pomoću cursor-FOR petlje.

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

Izlaz

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

Code Objašnjenje

  • Code redak 2: Deklarisanje kursora guru99_det za naredbu 'SELECT emp_name FROM emp'.
  • Code redak 4: Konstruiranje FOR petlje za kursor s varijablom petlje lv_emp_name.
  • Code redak 6: Ispisivanje imena zaposlenika u svakoj iteraciji petlje.
  • Code redak 7: Izlaz iz petlje (END LOOP).

Bilješka: U petlji kursora-FOR, atributi kursora se ne mogu koristiti, jer se otvaranje, dohvaćanje i zatvaranje kursora implicitno vrši u petlji FOR.

Pitanja i odgovori

REF KURSOR (kursorska varijabla) je pokazivač na skup rezultata upita. Za razliku od statičkog kursora, može otvarati različite upite tijekom izvođenja i prosljeđivati ​​rezultate između PL/SQL blokova ili klijentskim programima.

Normalni kursor dohvaća jedan redak po FETCH-u, što uzrokuje mnogo promjena konteksta. RASINSKO SAKUPLJANJE učitava mnogo redaka u kolekciju jednim dohvaćanjem, što znatno smanjuje opterećenje kod velikih skupova rezultata.

Da. Deklarirajte parametrizirani kursor kao što je CURSOR c(broj odjela) IS SELECT …, a zatim proslijedite vrijednosti na OPEN c(10). Parametri vam omogućuju ponovnu upotrebu jedne definicije kursora s različitim vrijednostima filtera.

FOR UPDATE zaključava retke koje kursor odabire tako da ih nitko drugi ne može mijenjati. WHERE CURRENT OF zatim ažurira ili briše točno onaj redak koji je upravo dohvaćen, bez ponavljanja uvjeta WHERE.

Otvoreni kursori zadržavaju svoju memoriju rezerviranom i uračunavaju se u ograničenje OPEN_CURSORS. Ostavljanje mnogo otvorenih kursora na kraju izaziva ORA-01000: prekoračen je maksimalan broj otvorenih kursora, stoga uvijek ZATVORI eksplicitni kursor nakon upotrebe.

Svaki FETCH prebacuje se između PL/SQL i SQL mehanizama. Tisuće takvih kontekstnih preklopnika se zbrajaju, tako da jedna SQL naredba temeljena na skupu ili BULK COLLECT obično obrađuje iste retke puno brže.

Da. GitHub kopilot iz komentara izrađuje eksplicitne petlje OPEN, FETCH i CLOSE ili petlje kursora FOR, dodaje provjere izlaza %NOTFOUND i predlaže nazive atributa, iako biste prvo trebali pregledati logiku.

AI asistenti označavaju red po red petlje kursora koje bi mogle postati SQL naredbe temeljene na skupovima ili BULK COLLECT, uočavaju nezatvorene kursore i objašnjavaju ponašanje %attribute. Ovaj pregled strojnog učenja poboljšava performanse prije nego što kod dođe u produkciju.

Sažmite ovu objavu uz: