Ugrás a fő tartalomhoz

PL/SQL kurzorok és kivételkezelés

Kurzorok​

Egy kurzor egy mutató, amely egy lekérdezés eredményhalmazára hivatkozik. Segítségével soronként dolgozhatjuk fel a rekordokat.

Kurzor típusai​

TípusLeírás
Implicit kurzorAz Oracle automatikusan létrehozza minden INSERT, UPDATE, DELETE, SELECT INTO utasítás után
Explicit kurzorA fejlesztő hozza létre névvel, ha több sort szeretne feldolgozni

Implicit kurzorok​

Az Oracle automatikusan kezeli őket, pl. SELECT INTO esetén. A SQL% attribútumokkal ellenőrizhetjük az utasítás eredményét.

Implicit kurzor attribútumok​

AttribútumLeírás
SQL%FOUNDTRUE, ha az utasítás legalább egy sort érintett
SQL%NOTFOUNDTRUE, ha egy sort sem érintett
SQL%ROWCOUNTAz érintett sorok száma
SQL%ISOPENImplicit kurzoroknál mindig FALSE

Példa – implicit kurzor használata​

BEGIN
UPDATE employees
SET salary = salary * 1.05
WHERE department_id = 50;

IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' sor frissítve.');
ELSE
DBMS_OUTPUT.PUT_LINE('Nincs frissíthető dolgozó.');
END IF;
END;

Explicit kurzorok​

Ha egy lekérdezés több sort ad vissza, explicit kurzort kell használni. Ezeket mi hozzuk létre, nyitjuk meg, olvassuk és zárjuk le.

Explicit kurzor attribútumok​

AttribútumJelentés
%FOUNDIgaz, ha a legutóbbi FETCH visszaadott sort
%NOTFOUNDIgaz, ha a FETCH nem adott vissza sort
%ROWCOUNTEddig beolvasott sorok száma
%ISOPENIgaz, ha a kurzor nyitva van

Példa - explicit kurzor létrehozása és használata​

DECLARE
CURSOR c_emps IS SELECT first_name, salary FROM employees;

v_name employees.first_name%TYPE;
v_salary employees.salary%TYPE;
BEGIN
OPEN c_emps; -- kurzor megnyitása
LOOP
FETCH c_emps INTO v_name, v_salary; -- következő sor beolvasása
EXIT WHEN c_emps%NOTFOUND; -- kilépés, ha nincs több sor
DBMS_OUTPUT.PUT_LINE(v_name || ': ' || v_salary);
END LOOP;
CLOSE c_emps; -- kurzor lezárása
END;

Kivételkezelés (EXCEPTION)​

A kivételkezelés segítségével a program hibák esetén sem szakad meg, hanem kezelni tudjuk azokat.

Kivételkezelés szerkezete​

BEGIN
-- fő logika
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Nincs ilyen adat.');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Túl sok sor tért vissza.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Ismeretlen hiba történt.');
DBMS_OUTPUT.PUT_LINE('Hibakód: ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE('Hibaüzenet: ' || SQLERRM);
END;

Beépített kivételek​

Kivétel neveMikor keletkezik
NO_DATA_FOUNDSELECT INTO nem ad vissza sort
TOO_MANY_ROWSSELECT INTO több sort ad vissza
ZERO_DIVIDEOsztás nullával
VALUE_ERRORTípuskonverziós hiba vagy túl nagy szám
OTHERSMinden egyéb hiba

Saját kivételek​

Saját kivételeket is definiálhatunk a DECLARE részben, és RAISE utasítással váltjuk ki őket.

Példa – saját kivétel használata​

DECLARE
e_low_salary EXCEPTION;
v_salary employees.salary%TYPE := 250000;
BEGIN
IF v_salary < 300000 THEN
RAISE e_low_salary;
END IF;

DBMS_OUTPUT.PUT_LINE('Fizetés rendben.');

EXCEPTION
WHEN e_low_salary THEN
DBMS_OUTPUT.PUT_LINE('A fizetés túl alacsony!');
END;

Feladatok​

1. Feladat​

Írj eljárást, amely:

Lekérdezi az employees tábla összes dolgozóját kurzorral akinek meghaladja a fizetése az 50000-et, majd kiírja a nevüket és fizetésüket.

2. Feladat​

Készíts programot, amely:

SELECT INTO utasítással lekérdezi egy dolgozó adatait ID alapján, kezeli a NO_DATA_FOUND és TOO_MANY_ROWS kivételeket.

3. Feladat​

Írj függvényt, amely:

Paraméterként kap egy fizetési értéket, saját kivételt dob, ha az kisebb 400000-nél, egyébként visszaadja a fizetést 10%-os bónusszal.