Oracle Kurzor PL/SQL: Implicitní, Explicitní, pro smyčku s příkladem

⚡ Chytré shrnutí

Kurzory v Oracle PL/SQL jsou ukazatele na kontextovou oblast, která obsahuje řádky vrácené příkazem SQL. Existují dva druhy: implicitní kurzory, vytvořené automaticky pro DML, a explicitní kurzory, deklarované a řízené programátorem.

  • 📍 Kontextová oblast: Kurzor ukazuje na kontextovou oblast, která ukládá příkaz SQL a jeho vrácenou aktivní sadu.
  • ⚙️ Implicitní kurzor: Oracle Automaticky otevírá implicitní kurzor pro každý příkaz DML a jednořádkový příkaz SELECT INTO.
  • Explicitní kurzor: Programátor deklaruje, otevírá, načítá a zavírá explicitní kurzor pro plnou kontrolu.
  • 🔎 Atributy kurzoru: %FOUND, %NOTFOUND, %ISOPEN a %ROWCOUNT hlásí stav poslední operace.
  • 🔁 Kurzorová smyčka FOR: Smyčka FOR implicitně otevírá, načítá a zavírá kurzor, takže nevyžaduje žádné ruční kroky.
  • 🤖 Asistence AI: Asistenti umělé inteligence, jako například GitHub Copilot, vytvářejí smyčky kurzorů v konceptu a označují neuzavřené kurzory.

Oracle Implicitní, explicitní a FOR smyčka v PL/SQL kurzoru

Co je CURSOR v PL/SQL?

Kurzor je ukazatel na kontextovou oblast. Oracle vytváří kontextovou oblast pro zpracování SQL výpis a tato oblast obsahuje veškeré informace o výpisu.

PL / SQL umožňuje programátorovi ovládat kontextovou oblast pomocí kurzoru. Kurzor obsahuje řádky vrácené příkazem SQL a sada řádků, které kurzor drží, se označuje jako aktivní sada. Tyto kurzory lze také pojmenovat tak, aby se na ně dalo odkazovat z jiného místa v kódu.

Kurzor je dvojího typu:

  • Implicitní kurzor
  • Explicitní kurzor

Implicitní kurzor

Kdykoli Operace DML V databázi se vytvoří implicitní kurzor, který obsahuje řádky ovlivněné danou operací. Tyto kurzory nelze pojmenovat, a proto je nelze ovládat ani se na ně odkazovat z jiného místa v kódu. Prostřednictvím atributů kurzoru se můžeme odkazovat pouze na nejnovější kurzor.

Explicitní kurzor

Programátoři si mohou vytvořit pojmenovanou kontextovou oblast pro provádění svých DML operací a získat nad ní větší kontrolu. Explicitní kurzor by měl být definován v deklarační sekci PL/SQL bloka je vytvořen pro příkaz SELECT, který je třeba v kódu použít.

Níže jsou uvedeny kroky potřebné k práci s explicitními kurzory:

  • Deklarace kurzoru: Deklarace kurzoru jednoduše znamená vytvoření jedné pojmenované kontextové oblasti pro příkaz SELECT, která je definována v deklarační části. Název této kontextové oblasti je stejný jako název kurzoru.
  • Otevření kurzoru: Otevření kurzoru dá PL/SQL pokyn k alokaci paměti pro tento kurzor. Kurzor je tak připraven k načítání záznamů.
  • Načítání dat z kurzoru: V tomto procesu se provede příkaz SELECT a načtené řádky se uloží do alokované paměti. Tyto se nyní nazývají aktivní sady. Načítání dat z kurzoru je aktivita na úrovni záznamu, což znamená, že k datům můžeme přistupovat záznam po záznamu. Každý příkaz fetch načte jednu aktivní sadu a uchovává informace o daném záznamu. Tento příkaz je stejný jako příkaz SELECT, který načte záznam a přiřadí ho proměnné v klauzuli INTO, ale nevyvolá žádné... výjimky.
  • Zavření kurzoru: Jakmile jsou všechny záznamy načteny, musíme zavřít kurzor, aby se uvolnila paměť přidělená této kontextové oblasti.

Syntax

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

Ve výše uvedené syntaxi obsahuje deklarační část deklaraci kurzoru a proměnnou kurzoru, do které budou přiřazena načtená data. Kurzor se vytvoří pro příkaz SELECT, který je zadán v deklaraci kurzoru. V prováděcí části se deklarovaný kurzor otevře, načte a zavře.

Atributy kurzoru

Implicitní i explicitní kurzor mají určité atributy, ke kterým lze přistupovat. Tyto atributy poskytují více informací o operacích s kurzorem. Níže jsou uvedeny různé atributy kurzoru a jejich použití.

Atribut kurzoru Description
%NALEZENO Vrací booleovský výsledek TRUE, pokud poslední operace načtení úspěšně načetla záznam; jinak vrací FALSE.
%NENALEZENO Funguje opačně než %FOUND. Vrací hodnotu TRUE, pokud poslední operace načtení nemohla načíst žádný záznam.
%JE OTEVŘENO Vrátí booleovskou hodnotu TRUE, pokud je daný kurzor již otevřený; jinak vrátí FALSE.
% ROWCOUNT Vrací číselnou hodnotu udávající skutečný počet záznamů ovlivněných nebo načtených operací.

Příklad explicitního kurzoru: V tomto příkladu uvidíme, jak deklarovat, otevřít, načíst a zavřít explicitní kurzor. Promítneme všechna jména zaměstnanců z tabulky emp pomocí kurzoru. Také použijeme atribut cursor k nastavení smyčky pro načítání všech záznamů z kurzoru.

Níže uvedený snímek obrazovky ukazuje tento příklad explicitního kurzoru a jeho výstup v Oracle.

Příklad explicitního kurzoru pro načítání jmen zaměstnanců z tabulky emp v 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;
/

Výstup

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

Code Vysvětlení

  • Code řádek 2: Deklarace kurzoru guru99_det pro příkaz 'SELECT emp_name FROM emp'.
  • Code řádek 3: Deklarace proměnné lv_emp_name s %typ ukotveno k emp.emp_name.
  • Code řádek 5: Otevření kurzoru guru99_det.
  • Code řádek 6: Nastavení základního příkazu smyčky pro načtení všech záznamů v tabulce emp.
  • Code řádek 7: Načte data guru99_det a přiřadí hodnotu k lv_emp_name.
  • Code řádek 8: Použití atributu kurzoru %NOTFOUND k ověření, zda byly načteny všechny záznamy v kurzoru. Pokud ano, vrátí hodnotu TRUE a řízení ukončí smyčku; jinak řízení pokračuje v načítání dat z kurzoru a tiskne je.
  • Code řádek 10: EXIT podmínka pro příkaz smyčky.
  • Code řádek 12: Vytiskněte načtené jméno zaměstnance.
  • Code řádek 14: Použití atributu kurzoru %ROWCOUNT k nalezení celkového počtu záznamů načtených kurzorem.
  • Code řádek 15: Po ukončení smyčky se kurzor uzavře a alokovaná paměť se uvolní.

FOR Příkaz kurzoru smyčky

Kurzor smyčka FOR lze použít pro práci s kurzory. V příkazu smyčky FOR můžeme zadat název kurzoru místo omezení rozsahu, takže smyčka bude fungovat od prvního záznamu kurzoru do posledního záznamu kurzoru. Proměnná kurzoru, otevření kurzoru, načtení a uzavření kurzoru jsou implicitně prováděny smyčkou FOR.

Syntax

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

Ve výše uvedené syntaxi obsahuje deklarační část deklaraci kurzoru. Kurzor je vytvořen pro příkaz SELECT, který je zadán v deklaraci kurzoru. V prováděcí části je deklarovaný kurzor nastaven ve smyčce FOR a proměnná smyčky 'I' se v tomto případě chová jako proměnná kurzoru.

Oracle Příklad kurzoru pro smyčku: V tomto příkladu promítneme všechna jména zaměstnanců z tabulky emp pomocí smyčky cursor-FOR.

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

Výstup

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

Code Vysvětlení

  • Code řádek 2: Deklarace kurzoru guru99_det pro příkaz 'SELECT emp_name FROM emp'.
  • Code řádek 4: Vytvoření smyčky FOR pro kurzor s proměnnou smyčky lv_emp_name.
  • Code řádek 6: Tisk jména zaměstnance v každé iteraci smyčky.
  • Code řádek 7: Ukončete smyčku (KONEC SMYČKY).

Poznámka: Ve smyčce kurzor-FOR nelze použít atributy kurzoru, protože otevírání, načítání a zavírání kurzoru se implicitně provádí smyčkou FOR.

Nejčastější dotazy

REFERENČNÍ KURZOR (kurzorová proměnná) je ukazatel na sadu výsledků dotazu. Na rozdíl od statického kurzoru může za běhu otevírat různé dotazy a předávat výsledky mezi bloky PL/SQL nebo klientským programům.

Normální kurzor načítá jeden řádek při každém FETCH, což způsobuje mnoho přepínání kontextu. VELKÝ SBĚR načte mnoho řádků do kolekce najednou, což výrazně snižuje režijní náklady u velkých sad výsledků.

Ano. Deklarujte parametrizovaný kurzor, například CURSOR c(dept NUMBER) IS SELECT …, a poté předejte hodnoty v OPEN c(10). Parametry umožňují opakovaně použít jednu definici kurzoru s různými hodnotami filtru.

Příkaz FOR UPDATE uzamkne řádky, které kurzor vybere, aby je nikdo jiný nemohl změnit. Příkaz WHERE CURRENT OF poté aktualizuje nebo smaže přesně ten řádek, který byl právě načten, bez opakování podmínky WHERE.

Otevřené kurzory si uchovávají rezervovanou paměť a započítávají se do limitu OPEN_CURSORS. Ponechání velkého počtu otevřených kurzorů nakonec vyvolá chybu ORA-01000: maximum open cursors exceeded, proto po použití vždy ZAVŘETE explicitní kurzor.

Každý příkaz FETCH přepíná mezi enginy PL/SQL a SQL. Takových přepínačů kontextu se nasčítají tisíce, takže jeden příkaz SQL založený na množině neboli BULK COLLECT obvykle zpracuje stejné řádky mnohem rychleji.

Ano. GitHub Copilot vytváří explicitní smyčky OPEN, FETCH a CLOSE nebo kurzorové smyčky FOR z komentáře, přidává kontroly ukončení %NOTFOUND a navrhuje názvy atributů, i když byste si nejprve měli prostudovat logiku.

Asistenti umělé inteligence označují řádkové smyčky kurzorů, které by se mohly stát SQL příkazy založenými na sadách nebo hromadnými sběry, identifikují neuzavřené kurzory a vysvětlují chování %attribute. Tato kontrola strojového učení zlepšuje výkon předtím, než se kód dostane do produkčního prostředí.

Shrňte tento příspěvek takto: