A PL/SQL programozási nyelv

Alprogramok, modulok

Blokkok

A Pl/SQL nyelv alapvető strukturális egysége a PL/SQL blokk. A blokk durva közelítéssel megfeleltethető a hagyományos programozási nyelven megírt eljárásoknak. A legfőbb hasonlósága az eljárással az, hogy a PL/SQL blokk is adatdefiníciós, majd azt követő műveleti részből áll, s a végrehajtás egységét jelenti. A különbség legfontosabb elemei, hogy itt szintaktikailag külön szerepel egy hibakezelő rész, s a blokkok egymásba is ágyazhatók, ahol a beágyazott blokk a műveleti vagy hibakezelő részben szerepelhet.

A blokk általános felépítését a következő ábra szemlélteti.

PL/SQL blokk

Az ábrában szereplő szavak a bevezető nyelvi utasításokat jelöli. A három szerkezeti elem közül csak a műveleti rész kötelező, a másik kettő elhagyható. A deklarációs részben a blokk saját, lokális változóit, memória változóit lehet megadni. A műveleti részben találhatók az SQL és procedurális utasítások, míg a hibakezelő rész a felmerülő adatkezelési hibákra adandó válaszokat definiálja.

Blokktípusok:

- Névtelen blokk
Akár SQL Plus környezetbe is begépelhető PL/SQL kód, ami egyszer lefut. Ha fájlba írjuk, akkor többször is lefuttatható a START fájlnév paranccsal. Ilyen névtelen blokk a triggerekben használt blokk is.

- Eljárás (procedure)
Az adatbázisban tárolt program. Névvel rendelkező PL/SQL blokk. Műveletek végezhetők vele, értékeket lehet átadni neki, illetve adhat is vissza értéket. Meghívható manuálisan és más PL/SQL blokkból is. (Szerkezetét később tárgyaljuk.)

- Függvény (function)
Az eljáráshoz hasonló. Mindig van egy visszatérési értéke, amelyet a hívás helyére ad vissza. Ezért a függvényeket kifejezés részeként hívjuk meg. (Szerkezetét később tárgyaljuk.)

A blokkok egymásba ágyazása esetén a beágyazott blokk is a BEGIN kulcsszóval kerül bevezetésre, s az END; utasítás zárja le.

A hagyományos alprogramokhoz, eljárásokhoz szokott programozóknak feltűnhet, hogy a blokkok deklarálásánál hiányzik egy blokk azonosító. A PL/SQL rendszerben valóban nincs felhasználó által adott egyedi neve a blokkoknak. Ebből következően a blokkok önmagukban nem hívhatók meg más blokkokból. A későbbiekben látható lesz, hogy a PL/SQL blokkok igazából ritkán használatosak önmagukban, mindig valamilyen környezetben, más típusú objektumok(pl. tárolt eljárások, triggerek) részeként jelenik meg, melyeknek már van egyedi azonosító neve, így a befoglaló objektumokon keresztül tudunk a letárolt blokkokra hivatkozni.

A blokkok egymásba ágyazásához kapcsolódóan megemlítjük, hogy a beágyazott blokk a külső blokk részeként kezelendő. Így például a külső blokkban deklarált változók a beágyazott blokkban is láthatók lesznek. Az alblokk függetlensége abban nyilvánul meg, hogy ő maga is hozhat létre saját változókat, melyek azonos azonosító nevet is kaphatnak, mint a külső blokkban létrehozott változók. Ez utóbbi esetben a belső blokkban deklarált változó egy új változó lesz, amely az alblokkban elrejti a kinn deklarált ugyanilyen nevű változót. A lokálisan létrehozott változónak tehát itt is elsőbbsége van a külső változókkal szemben.

DECLARE -- Főblokk kezdete /* Változók, konstansok, cursorszerkezetek és hibakezelési elemek deklarálása */ BEGIN -- Főblokk műveleti részének kezdete /* Utasítások, SQL parancsok, Vezérlési elemek */ DECLARE -- Alblokk kezdete ... BEGIN -- Alblokk műveleti része ... EXCEPTION -- Alblokk hibakezelő része ... END; -- Alblokk vége EXCEPTION -- Főblokk hibakezelő része /* Hibakezelő műveletek leírása */ END; -- Főblokk vége

Szintaxis

Eljárás deklarálás

PROCEDURE name [(parameter[, parameter, ...])] IS [local declarations] BEGIN executable statements [EXCEPTION exception handlers] END [name];

A paraméterek megadása a következőképpen történik:

parameter_name [IN | OUT | IN OUT] datatype [{:= | DEFAULT} expression]

Példa:

PROCEDURE Activate_Item (item_name IN VARCHAR2, ertek IN BOOLEAN) IS BEGIN IF ertek THEN Set_Item_Property(item_name, ENABLED, PROPERTY_TRUE); ELSE Set_Item_Property(item_name, ENABLED, PROPERTY_FALSE); END IF; END;

Függvény deklarálása

FUNCTION name [(parameter[, parameter, ...])] RETURN datatype IS [local declarations] BEGIN executable statements [EXCEPTION exception handlers] END [name];

A paraméterek megadása a következőképpen történik:

parameter_name [IN | OUT | IN OUT] datatype [{:= | DEFAULT} expression]

Példa:

FUNCTION Szamjegy_e(s VARCHAR2) RETURN BOOLEAN IS BEGIN IF s >= '0' AND s <= '9' THEN RETURN TRUE; END IF; RETURN FALSE; END;

Tulajdonságok

Tárolt eljárások

A tárolt eljárások egy olyan PL/SQL blokkot jelentenek, amelyek egyrészt paraméterezhetők, saját egyedi azonosító nevük van és az adatbázisban lefordított formában letárolásra kerülnek. E megoldásnak az az előnye, hogy a PL/SQL blokk több helyről is elérhető, elég csak egyszer definiálni, így gyorsabb végrehajtást tesz lehetővé, mint az egyedileg elküldött PL/SQL blokk.
Az eljárás deklarációja

CREATE PROCEDURE eljárásnév (paraméterlista) AS PL/SQL_blokk;

ahol a PL/SQL_blokk az eljárás törzse, s megfelel egy szabályos PL/SQL blokknak. A paraméterlista elemei veszővel vannak elválasztva egymástól, s minden elem paraméternév jelleg adattípus hármasból áll, melyben a jelleg arra utal, hogy kimenő vagy bejövő paraméterről van-e szó. Ennek megfelelően a jelleg lehetséges értékei:

IN - bementi paraméter OUT - kimeneti paraméter IN OUT - mindkét irányba mutató adatforgalmat lebonyolító paraméter

Az adattípus a szokásos PL/SQL adattípusok valamelyike lehet. A törzsben szereplő PL/SQL blokkban a paraméterek ugyanúgy használhatók, mint a normál PL/SQL változók, így nem kell eléjük kettőspontot sem tenni a hivatkozáskor. A PL/SQL blokk jellemzője, hogy nem kell benne DECLARE kulcsszót megadni a blokk kezdetének kijelölésére. A tárolt függvények definíciója hasonló az eljárások definíciójához, azzal a különbséggel, hogy itt visszatérési érték is értelmezett. A visszatérési érték típusát a paraméterlistát követően, a zárójel után megadott RETURN adattípus taggal jelöljük. A visszatérési értéket a RETURN utasítással határozzuk meg, mint az alábbi példa is mutatja. A példa adott típusú autók átlagárát határozza meg.

CREATE FUNCTION atlag (tip IN CHAR(20)) RETURN NUMBER IS ertek NUMBER; BEGIN SELECT AVG(ar) INTO ertek FROM autok WHERE tipus LIKE tip; RETURN (ertek); END;

Az eljárások, függvények felhasználása az alkalmazott fejlesztő eszköztől függ.
Ahhoz hogy egy függvényt SQL utasításban is használhassunk, az alábbi megszorításoknak kell eleget tennie:

Package-ek

A package-ben lehetnek procedúrák, függvények, típus definíciók, változó deklarációk, konstansok, kivételek, kurzorok. Két része a specifikációs rész és a törzs (body). A specifikációs részben vannak a publikus deklarációk.
Ennek létrehozása (SQL utasítással):

CREATE OR REPLACE PACKAGE p_név IS publikus típus és objektum deklarációk alprogram specifikációk END;

A body-ban vannak az alprogramok és a kurzorok implementációi. Csak ezeknek van implementációs része, így ha a package csak más objektumokat tartalmaz (változók, típusok, kivételek ... stb.) akkor nem is kell hogy body-ja is legyen.
A kurzorok kétféleképpen is megadhatók.
1. Vagy a specifikációban adjuk meg őket a szokásos módon, ekkor nem is szerepelnek az implementációs részben.
2. A specifikációs részben csak a nevét és a sortípusát adjuk meg (CURSOR C1 RETURN ) és az implementációs részben adjuk meg a SELECT-et.

CREATE OR REPLACE PACKAGE BODY p_név IS privát típus és objektum deklarációk alprogramok törzse (PROCEDURE ... IS ...) kurzorok (CURSOR C1 RETURN IS SELECT ...) [BEGIN inicializáló utasítások ] END;

A body-ban vannak az implementációk és lehet neki inicializációs része is (BEGIN ... END között), ami csak egyszer fut le, amikor a package-re először hivatkoznak.

A package specifikációs részében szereplő objektumok lokálisak az adatbázissémára nézve és globálisak a package-re nézve. A package-beli objektumokra hivatkozhatunk is: p_név.obj.
A STANDARD package-beli objektumokra hivatkozhatunk a p_név nélkül.

Lehet azonos a neve két package-ben levő alprogramnak, amelyeknek más a paraméterezése. Ilyenkor híváskor derül ki, hogy melyik fog futni a formális és aktuális paraméterek egyeztetésekor (overloading). Például a STANDARD package-ben van több verzió is a TO_CHAR fv-re.

A package-ek legfontosabb előnyei:

A package-ek forrásszövege a DBA_SOURCE táblában megnézhető.

A legfontosabb package-ek:

Paraméterátadás

PL/SQL-ben lehetőségünk van eljárások és függvények használatára. Alprogram hívásakor a formális és aktuális paraméterek összerendelése történhet pozíció, név vagy mindkettő szerint. A név szerinti hozzárendelés formája: formális_paraméter => aktuális_paraméter A PL/SQL háromféle paraméterátadási módot ismer: