„Adatbázisok szerver oldali programozása” változatai közötti eltérés
Új oldal, tartalma: „{{GlobalTemplate|Valaszthato|AdatbServerProg}} Tantárgy adatlap: * http://www.vdk.bme.hu/targykov/valaszthato/viau9159.htm Tanszéki oldal: * https://avalon.aut.bme…” |
Nincs szerkesztési összefoglaló |
||
1. sor: | 1. sor: | ||
{{GlobalTemplate|Valaszthato| | {{GlobalTemplate|Valaszthato|AdatbServerProgJegyzet20060317}} | ||
<!-- | |||
* Set DENYTOPICVIEW = [[TWikiGuest]] | |||
--> | |||
<style> | |||
code.pre { white-space: pre; display: block; margin-top: 2px; margin-bottom: 2px;} | |||
li { line-height: 18px; } | |||
</style> | |||
<br/> [[AdatbServerProgJegyzet20060314|<<]] Előadás, 2006.03.17. [[AdatbServerProgJegyzet20060321|>>]] | |||
__TOC__ | |||
=== | ==Kivételek kezelése== | ||
=== | ===Kivétel típusok=== | ||
* Rendszer kivételek | |||
** Névvel ellátott kivételek (név, sorszám, üzenet) | |||
** Név nélküli kivételek (sorszám, üzenet) | |||
* Felhasználói kivételek | |||
* Alkalmazás hibák | |||
====Névvel ellátott kivételek==== | |||
= | * Kivétel lekezelése: <code class="pre">DECLARE ... | ||
<br/>BEGIN ... | |||
<br/>EXCEPTION | |||
* | <br/> WHEN kivételnév [OR kivételnév2 [...]] THEN utasítások; | ||
* | <br/> WHEN OTHERS THEN utasítások; | ||
** | <br/>END;</code> | ||
** | * Az =OTHERS= blokknak a =EXCEPTION= blokk végére kell kerülnie. | ||
** | * Gyakori, névvel ellátott kivételek: | ||
*** | ** =NO_DATA_FOUND= | ||
* | ** =TOO_MANY_ROWS= | ||
** | ** =DUP_VAL_ON_INDEX=: olyan sort akarunk beszúrni, amivel megszegjük a kulcs vagy a =UNIQUE= oszlop egyediségére vonatkozó megkötést | ||
** | ** =VALUE_ERROR=: pl. =NULL= értéket akarunk beszúrni =NOT NULL= oszlopba | ||
** | ** =ZERO_DIVIDE= | ||
* | ** =CURSOR_ALREADY_OPEN=: kétszer nyitunk meg egy kurzort | ||
* | ** =INVALID_CURSOR= | ||
** =CASE_NOT_FOUND=: a =CASE= utasítás szelektora egyik ágra sem illeszkedik | |||
* A nevek a =STANDARD= csomagban vannak összegyűjtve. Nem kell deklarálni őket. | |||
* Kivétel generálása: =RAISE NO_DATA_FOUND;= | |||
* | ====Név nélküli rendszer kivételek==== | ||
* A =WHEN OTHERS= blokkban egyszerre elkaphatók | |||
* Elnevezhetők a =PRAGMA= utasítás segítségével: <code class="pre">DECLARE kivételnév EXCEPTION; | |||
<br/>PRAGMA EXCEPTION_INIT(kivételnév, szám);</code> | |||
* Az előbbi módon a rendszer kivételnevek is felüldefiniálhatók. Az eredeti kivételre a =STANDARD= előtaggal hivatkozhatunk. Pl. =WHEN STANDARD.NO_DATA_FOUND THEN ...= | |||
* Kivétel generálása: =RAISE kivételnév;= | |||
====Felhasználói kivételek==== | |||
<ul> | |||
<li>Szintaktika: | |||
<code class="pre">DECLARE | |||
kivételnév EXCEPTION; | |||
BEGIN | |||
... | |||
RAISE kivételnév; | |||
... | |||
EXCEPTION | |||
WHEN kivételnév THEN ... | |||
END;</code> | |||
</ul> | |||
* {{ | ====Alkalmazás hibák==== | ||
* Hiba kiváltása: =RAISE_APPLICATION_ERROR(hibakód, üzenet[, {FALSE|TRUE}])= | |||
** hibakód: -20999 és -20000 közötti szám | |||
** üzenet: =VARCHAR(2048)= | |||
** A 3. paraméter =TRUE= értéke esetén a hiba a stackbe kerül, különben felülírja az előző hibát. A paraméter alapértelmezett értéke =FALSE= | |||
===Kivételek terjedése=== | |||
* A =DECLARE= és =BEGIN= között keletkezett hibát csak kívül lehet elkapni. | |||
* Ugyanez igaz az =EXCEPTION= és az =END= között keletkezett kivételre is. | |||
* A =BEGIN= és az =EXCEPTION= közötti kivétel az =EXCEPTION= blokkban lekezelhető. Ha itt nem történik meg, akkor a külső blokk =EXCEPTION= részébe terjed tovább. | |||
* A belső blokkban lokálisan deklarált hibát a külső blokknak csak a =WHEN OTHERS= részében lehet elkapni, mert kívül nem látható a neve. | |||
===Hibakód és hibaüzenet=== | |||
<ul> | |||
<li> Az =SQLCODE= illetve az =SQLERRM= függvényekkel kérdezhető le. | |||
<li> Ezek a függvények nek használhatók SQL utasítások belsejében, az értéküket először változóba kell kiolvasni. | |||
<li> Példa a hibák naplózására: | |||
<code class="pre">DECLARE | |||
hibakod INT; | |||
uzenet VARCHAR2(512); | |||
BEGIN | |||
... | |||
EXCEPTION | |||
WHEN OTHERS THEN | |||
szam := SQLCODE; | |||
uzenet := SQLERRM; | |||
INSERT INTO naplo VALUES (szam, uzenet, sysdate); | |||
END;</code> | |||
</ul> | |||
====Hibakódok==== | |||
* Belső kivétel: <0 | |||
* =NO_DATA_FOUND=: 100 | |||
* Felhasználói kivétel: 1 | |||
* Nincs hiba: 0 | |||
====Hibaüzenetek==== | |||
* A rendszerüzenetek =VARCHAR2(512)= típusúak | |||
* Felhasználói kivétel esetén a ='User Defined Exception'= üzenetet kapjuk | |||
* Siker esetén ='ORA-0000'= az üzenet | |||
==Alprogramok== | |||
===Alprogramok típusai, terminológia=== | |||
* Lehetnek eljárások vagy függvények | |||
* Lehetnek tároltak vagy lokálisak | |||
* Részei: deklaráció, kód, kivételkezelés | |||
* _Formális paraméter_: a paraméter neve | |||
* _Aktuális paraméter_: a paraméter értéke | |||
===Eljárások és függvények=== | |||
<ul> | |||
<li> Eljárás deklarációja: | |||
<code class="pre">[CREATE [OR REPLACE]] PROCEDURE eljárásnév [(paraméterek)] | |||
[AUTHID {DEFINER|CURRENT_USER}] | |||
{IS|AS} | |||
lokális deklaráció | |||
BEGIN | |||
... | |||
EXCEPTION | |||
... | |||
END [eljárásnév];</code> | |||
<li> Függvény deklarációja: | |||
<code class="pre">[CREATE [OR REPLACE]] FUNCTION függvénynév [(paraméterek)] | |||
RETURN típus | |||
[AUTHID {DEFINER|CURRENT_USER}] | |||
{IS|AS} | |||
lokális deklaráció | |||
BEGIN | |||
... | |||
RETURN érték; | |||
EXCEPTION | |||
... | |||
END [függvénynév];</code> | |||
<li>Paraméter deklaráció: | |||
<br/> =név [IN|OUT [NOCOPY]||IN OUT [NOCOPY]] típus [{:=DEFAULT} kifejezés]= | |||
</ul> | |||
====Paraméter módok==== | |||
* A típus nem tartalmazhat megkötést, mint pl. =VARCHAR2(50)= | |||
* =IN=: alapértelmezett mód, eljáráson belül konstansként viselkedik, lehet default értéke | |||
* =OUT=: változóként viselkedik, változóval kell meghívni. Hívás után <pre>NULL</pre>-ra inicializálódik, ezért nem lehet =NOT NULL= megkötést tenni a típusra, különben =VALUE_ERROR= hibát kapunk. | |||
* =OUT NOCOPY=: referenciaként adódik át a változó. Vigyáznunk kell, ha kivétel történik, mert inkonzisztens állapotban maradhat a változó értéke | |||
* =IN OUT=: értékadás bal és jobb oldalán is állhat | |||
====Eljárás hívása==== | |||
* =BEGIN= és =END= között =eljárásnév(paraméterek);= | |||
* Command windowból =EXEC eljárásnév(paraméterek);= | |||
* Paraméterek átadása | |||
** A paraméter lehet konstans, változó vagy kifejezés | |||
** Paraméterátadás pozíció alapján: | |||
<br/> =eljárásnév(érték, ...);= | |||
** Paraméterátadás név alapján: | |||
<br/> =eljárásnév(formális paraméter=>aktuális paraméter, ...);= | |||
** Kevert paraméterátadás: az első néhány paramétert pozíció alapján, a többit név alapján adjuk át. | |||
* Függvényhívás történhet | |||
** Kifejezés részeként | |||
** =SELECT= belsejében, pl. =SELECT f(1) FROM DUAL;=. Ilyenkor a függvénynek SQL típussal kell visszatérnie, a boolean például tiltott. | |||
===Példák=== | |||
====Tárolt eljárás hibakezeléssel==== | |||
<code class="pre">CREATE OR REPLACE PROCEDURE anyag_beszur | |||
(azonosito INT, nev VARCHAR2, egyszegnev VARCHAR2) | |||
IS | |||
egysegid INT; | |||
BEGIN | |||
SELECT egyseg_id INTO egysegid FROM egyseg | |||
WHERE UPPER(egyseg_nev) = UPPER(egysegnev); | |||
INSERT INTO anyag(anyag_id, anyag_nev, anyag_egyseg) | |||
VALUES(azonosito, ne, egysegid); | |||
EXCEPTION | |||
WHEN NO_DATA_FOUND THEN | |||
RAISE_APPLICATION_ERROR(-20101, 'Nincs ilyen egység'); | |||
WHEN DUP_VAL_ON_INDEX THEN | |||
BEGIN | |||
SELECT anya_id INTO aid FROM anyag | |||
WHERE UPPER(anyag_nev) = UPPER(nev); | |||
RAISE_APPLICATION_ERROR(-20102, 'Az anyag létezik ' ||| aid || ' azonosítóval'); | |||
EXCEPTION | |||
WHEN NO_DATA_FOUND THEN | |||
SELECT MAX(anyag_id)+1 INTO aid FROM anyag; | |||
RAISE_APPLICATION_ERROR(-20103, 'Dupla azonosító, ajánlott: ' | aid'); | |||
END; | |||
END anyag_beszur;</code> | |||
====Tárolt eljárás név nélküli hiba kezelésével==== | |||
<code class="pre">CREATE OR REPLACE PROCEDURE recept_beszur | |||
(aid INT, fid INT, mennyiseg FLOAT) -- aid=anyag id, fid=félkész id | |||
IS | |||
referencia EXCEPTION; | |||
PRAGMA EXCEPTION_INIT(referencia, -2291); | |||
BEGIN | |||
INSERT INTO felkesz_anyag VALUES(aid, fid, mennyiseg); | |||
EXCEPTION | |||
WHEN referencia THEN | |||
RAISE ... -- itt még lehetne ellenőrizni, hogy melyik oszlop okozza | |||
WHEN DUP_VAL_ON_INDEX THEN | |||
RAISE ... | |||
END;</code> | |||
====Tárolt függvény hibakezeléssel==== | |||
<code class="pre">CREATE OR REPLACE FUNCTION pilota_pontszam(pid INT, fid INT) | |||
RETURN INT | |||
IS | |||
result INT; | |||
sorszam INT; | |||
BEGIN | |||
SELECT helyezes [[INTo]] sorszam FROM futam_pilota | |||
WHERE futam_id=fid AND pilota_id=pid; | |||
CASE sorszam | |||
WHEN 1 THEN result:=10; | |||
WHEN 2 THEN result:=8; | |||
WHEN 3 THEN result:=6; | |||
... | |||
WHEN 8 THEN result:=1; | |||
ELSE result:=0; | |||
END CASE; | |||
RETURN result; | |||
EXCEPTION | |||
WHEN NO_DATA_FOUND THEN | |||
RAISE ... | |||
END;</code> | |||
====Tárolt eljárás hívása==== | |||
<code class="pre">SELECT nev, helyezes, pilota_pontszam(pilotaid, futamid) pont | |||
FROM futam_pilota NATURAL JOIN pilota | |||
WHERE futamid=51001 | |||
ORDER BY helyezes, pont DESC;</code> | |||
A =WHERE= után nem lehet =pont= néven hivakozni a függvény eredményére, ki kell írni az egész függvényhívást. | |||
-- [[PallosPeter|Peti]] - 2006.03.17. | |||
[[Category:Valaszthato]] | [[Category:Valaszthato]] |
A lap 2013. március 31., 19:48-kori változata
Ez az oldal a korábbi SCH wikiről lett áthozva.
Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!
Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.
<style> code.pre { white-space: pre; display: block; margin-top: 2px; margin-bottom: 2px;} li { line-height: 18px; } </style>
Kivételek kezelése
Kivétel típusok
- Rendszer kivételek
- Névvel ellátott kivételek (név, sorszám, üzenet)
- Név nélküli kivételek (sorszám, üzenet)
- Felhasználói kivételek
- Alkalmazás hibák
Névvel ellátott kivételek
- Kivétel lekezelése:
DECLARE ...
BEGIN ...
EXCEPTION
WHEN kivételnév [OR kivételnév2 [...]] THEN utasítások;
WHEN OTHERS THEN utasítások;
END;
- Az =OTHERS= blokknak a =EXCEPTION= blokk végére kell kerülnie.
- Gyakori, névvel ellátott kivételek:
- =NO_DATA_FOUND=
- =TOO_MANY_ROWS=
- =DUP_VAL_ON_INDEX=: olyan sort akarunk beszúrni, amivel megszegjük a kulcs vagy a =UNIQUE= oszlop egyediségére vonatkozó megkötést
- =VALUE_ERROR=: pl. =NULL= értéket akarunk beszúrni =NOT NULL= oszlopba
- =ZERO_DIVIDE=
- =CURSOR_ALREADY_OPEN=: kétszer nyitunk meg egy kurzort
- =INVALID_CURSOR=
- =CASE_NOT_FOUND=: a =CASE= utasítás szelektora egyik ágra sem illeszkedik
- A nevek a =STANDARD= csomagban vannak összegyűjtve. Nem kell deklarálni őket.
- Kivétel generálása: =RAISE NO_DATA_FOUND;=
Név nélküli rendszer kivételek
- A =WHEN OTHERS= blokkban egyszerre elkaphatók
- Elnevezhetők a =PRAGMA= utasítás segítségével:
DECLARE kivételnév EXCEPTION;
PRAGMA EXCEPTION_INIT(kivételnév, szám);
- Az előbbi módon a rendszer kivételnevek is felüldefiniálhatók. Az eredeti kivételre a =STANDARD= előtaggal hivatkozhatunk. Pl. =WHEN STANDARD.NO_DATA_FOUND THEN ...=
- Kivétel generálása: =RAISE kivételnév;=
Felhasználói kivételek
- Szintaktika:
DECLARE kivételnév EXCEPTION; BEGIN ... RAISE kivételnév; ... EXCEPTION WHEN kivételnév THEN ... END;
Alkalmazás hibák
- Hiba kiváltása: =RAISE_APPLICATION_ERROR(hibakód, üzenet[, {FALSE|TRUE}])=
- hibakód: -20999 és -20000 közötti szám
- üzenet: =VARCHAR(2048)=
- A 3. paraméter =TRUE= értéke esetén a hiba a stackbe kerül, különben felülírja az előző hibát. A paraméter alapértelmezett értéke =FALSE=
Kivételek terjedése
- A =DECLARE= és =BEGIN= között keletkezett hibát csak kívül lehet elkapni.
- Ugyanez igaz az =EXCEPTION= és az =END= között keletkezett kivételre is.
- A =BEGIN= és az =EXCEPTION= közötti kivétel az =EXCEPTION= blokkban lekezelhető. Ha itt nem történik meg, akkor a külső blokk =EXCEPTION= részébe terjed tovább.
- A belső blokkban lokálisan deklarált hibát a külső blokknak csak a =WHEN OTHERS= részében lehet elkapni, mert kívül nem látható a neve.
Hibakód és hibaüzenet
- Az =SQLCODE= illetve az =SQLERRM= függvényekkel kérdezhető le.
- Ezek a függvények nek használhatók SQL utasítások belsejében, az értéküket először változóba kell kiolvasni.
- Példa a hibák naplózására:
DECLARE hibakod INT; uzenet VARCHAR2(512); BEGIN ... EXCEPTION WHEN OTHERS THEN szam := SQLCODE; uzenet := SQLERRM; INSERT INTO naplo VALUES (szam, uzenet, sysdate); END;
Hibakódok
- Belső kivétel: <0
- =NO_DATA_FOUND=: 100
- Felhasználói kivétel: 1
- Nincs hiba: 0
Hibaüzenetek
- A rendszerüzenetek =VARCHAR2(512)= típusúak
- Felhasználói kivétel esetén a ='User Defined Exception'= üzenetet kapjuk
- Siker esetén ='ORA-0000'= az üzenet
Alprogramok
Alprogramok típusai, terminológia
- Lehetnek eljárások vagy függvények
- Lehetnek tároltak vagy lokálisak
- Részei: deklaráció, kód, kivételkezelés
- _Formális paraméter_: a paraméter neve
- _Aktuális paraméter_: a paraméter értéke
Eljárások és függvények
- Eljárás deklarációja:
[CREATE [OR REPLACE]] PROCEDURE eljárásnév [(paraméterek)] [AUTHID {DEFINER|CURRENT_USER}] {IS|AS} lokális deklaráció BEGIN ... EXCEPTION ... END [eljárásnév];
- Függvény deklarációja:
[CREATE [OR REPLACE]] FUNCTION függvénynév [(paraméterek)] RETURN típus [AUTHID {DEFINER|CURRENT_USER}] {IS|AS} lokális deklaráció BEGIN ... RETURN érték; EXCEPTION ... END [függvénynév];
- Paraméter deklaráció:
=név [IN|OUT [NOCOPY]||IN OUT [NOCOPY]] típus [{:=DEFAULT} kifejezés]=
Paraméter módok
- A típus nem tartalmazhat megkötést, mint pl. =VARCHAR2(50)=
- =IN=: alapértelmezett mód, eljáráson belül konstansként viselkedik, lehet default értéke
- =OUT=: változóként viselkedik, változóval kell meghívni. Hívás után
NULL
-ra inicializálódik, ezért nem lehet =NOT NULL= megkötést tenni a típusra, különben =VALUE_ERROR= hibát kapunk. - =OUT NOCOPY=: referenciaként adódik át a változó. Vigyáznunk kell, ha kivétel történik, mert inkonzisztens állapotban maradhat a változó értéke
- =IN OUT=: értékadás bal és jobb oldalán is állhat
Eljárás hívása
- =BEGIN= és =END= között =eljárásnév(paraméterek);=
- Command windowból =EXEC eljárásnév(paraméterek);=
- Paraméterek átadása
- A paraméter lehet konstans, változó vagy kifejezés
- Paraméterátadás pozíció alapján:
=eljárásnév(érték, ...);=
- Paraméterátadás név alapján:
=eljárásnév(formális paraméter=>aktuális paraméter, ...);=
- Kevert paraméterátadás: az első néhány paramétert pozíció alapján, a többit név alapján adjuk át.
- Függvényhívás történhet
- Kifejezés részeként
- =SELECT= belsejében, pl. =SELECT f(1) FROM DUAL;=. Ilyenkor a függvénynek SQL típussal kell visszatérnie, a boolean például tiltott.
Példák
Tárolt eljárás hibakezeléssel
CREATE OR REPLACE PROCEDURE anyag_beszur
(azonosito INT, nev VARCHAR2, egyszegnev VARCHAR2)
IS
egysegid INT;
BEGIN
SELECT egyseg_id INTO egysegid FROM egyseg
WHERE UPPER(egyseg_nev) = UPPER(egysegnev);
INSERT INTO anyag(anyag_id, anyag_nev, anyag_egyseg)
VALUES(azonosito, ne, egysegid);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20101, 'Nincs ilyen egység');
WHEN DUP_VAL_ON_INDEX THEN
BEGIN
SELECT anya_id INTO aid FROM anyag
WHERE UPPER(anyag_nev) = UPPER(nev);
RAISE_APPLICATION_ERROR(-20102, 'Az anyag létezik ' ||| aid || ' azonosítóval');
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT MAX(anyag_id)+1 INTO aid FROM anyag;
RAISE_APPLICATION_ERROR(-20103, 'Dupla azonosító, ajánlott: ' | aid');
END;
END anyag_beszur;
Tárolt eljárás név nélküli hiba kezelésével
CREATE OR REPLACE PROCEDURE recept_beszur
(aid INT, fid INT, mennyiseg FLOAT) -- aid=anyag id, fid=félkész id
IS
referencia EXCEPTION;
PRAGMA EXCEPTION_INIT(referencia, -2291);
BEGIN
INSERT INTO felkesz_anyag VALUES(aid, fid, mennyiseg);
EXCEPTION
WHEN referencia THEN
RAISE ... -- itt még lehetne ellenőrizni, hogy melyik oszlop okozza
WHEN DUP_VAL_ON_INDEX THEN
RAISE ...
END;
Tárolt függvény hibakezeléssel
CREATE OR REPLACE FUNCTION pilota_pontszam(pid INT, fid INT)
RETURN INT
IS
result INT;
sorszam INT;
BEGIN
SELECT helyezes INTo sorszam FROM futam_pilota
WHERE futam_id=fid AND pilota_id=pid;
CASE sorszam
WHEN 1 THEN result:=10;
WHEN 2 THEN result:=8;
WHEN 3 THEN result:=6;
...
WHEN 8 THEN result:=1;
ELSE result:=0;
END CASE;
RETURN result;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE ...
END;
Tárolt eljárás hívása
SELECT nev, helyezes, pilota_pontszam(pilotaid, futamid) pont
FROM futam_pilota NATURAL JOIN pilota
WHERE futamid=51001
ORDER BY helyezes, pont DESC;
A =WHERE= után nem lehet =pont= néven hivakozni a függvény eredményére, ki kell írni az egész függvényhívást.
-- Peti - 2006.03.17.