„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]] | ||