• Nem Talált Eredményt

fejezet - Programegységek

In document PL/SQL programozás (Pldal 76-80)

SELECT INTO

6. fejezet - Programegységek

A PL/SQL nyelv a blokkszerkezetű nyelvek közé tartozik. A procedurális nyelveknél szokásos programegységek közül a PL/SQL a következő hármat ismeri:

• blokk,

• alprogram,

• csomag.

A blokkot és alprogramot ebben a fejezetben, a csomagot a 10. fejezetben tárgyaljuk.

1. A blokk

A blokk a PL/SQL alapvető programegysége. Kezelhető önállóan és beágyazható más programegységbe, ugyanis a blokk megjelenhet bárhol a programban, ahol végrehajtható utasítás állhat. A blokk felépítése a következő:

[címke] [DECLARE deklarációk]

BEGIN utasítás [utasítás]…

[EXCEPTION kivételkezelő]

END [címke];

Egy blokk lehet címkézett vagy címkézetlen (anonim). Egy címkézetlen blokk akkor kezd el működni, ha szekvenciálisan rákerül a vezérlés. A címkézett blokkra viszont ezen túlmenően GOTO utasítással is át lehet adni a vezérlést.

A blokknak három alapvető része van: deklarációs, végrehajtható és kivételkezelő rész. Ezek közül az első és utolsó opcionális.

A DECLARE alapszóval kezdődő deklarációs részben a blokk lokális eszközeit deklaráljuk, ezek az alábbiak lehetnek:

• típus,

• nevesített konstans,

• változó,

• kivétel,

• kurzor,

• alprogram.

Az alprogramok deklarációja csak az összes többi eszköz deklarációja után helyezhető el.

A BEGIN alapszó után tetszőleges végrehajtható utasítássorozat áll. Ezek egy adott algoritmus leírását teszik lehetővé.

Az EXCEPTION alapszó után kivételkezelő áll, ennek részleteit a 7. fejezet tárgyalja.

A blokkot záró END nem jelenti egy tranzakció végét. Egy blokk működése szétosztható több tranzakcióba és egy tranzakció akárhány blokkot tartalmazhat.

A blokk működése befejeződik, ha

Programegységek

• elfogynak a végrehajtható utasításai, ekkor beágyazott blokknál a blokkot követő utasításra, egyébként a hívó környezetbe kerül a vezérlés;

• kivétel következik be (lásd 7. fejezet);

• ha GOTO-val kiugrunk belőle (ez csak beágyazott blokknál lehetséges);

• a RETURN utasítás hatására (ekkor az összes tartalmazó blokk is befejeződik).

Példa /* Blokk */

<<kulso>>

DECLARE

s VARCHAR2(30) := 'hal';

BEGIN

/* beágyazott blokk */

DECLARE

s2 VARCHAR2(20) := 'El_lgató fej_lgató';

BEGIN

-- s2 is és s is látható

DBMS_OUTPUT.PUT_LINE(s); -- 'hal' s := REPLACE(s2, '_', s);

-- blokk vége END;

DBMS_OUTPUT.PUT_LINE(s); -- 'Elhallgató fejhallgató'

/* A következő sor fordítási hibát eredményezne, mert s2 már nem látható.

DBMS_OUTPUT.PUT_LINE(s2);

*/

<<belso>>

DECLARE

sNUMBER; -- elfedi a külső blokkbeli deklarációt BEGIN

s := 5;

belso.s := 7;

kulso.s := 'Almafa';

GOTO ki;

-- Ide soha nem kerülhet a vezérlés.

DBMS_OUTPUT.PUT_LINE('Sikertelen GOTO ?!');

END;

DBMS_OUTPUT.PUT_LINE(s); -- 'Almafa'

Programegységek

<<ki>>

BEGIN

/* A következő érték nem fér bele a változóba, VALUE_ERROR kivétel váltódik ki.*/

s := '1234567890ABCDEFGHIJ1234567890ABCDEFGHHIJ';

-- A kivétel miatt ide nem kerülhet a vezérlés.

DBMS_OUTPUT.PUT_LINE('Mégiscsak elfért az a sztring a változóban.');

DBMS_OUTPUT.PUT_LINE(s);

EXCEPTION

WHEN VALUE_ERROR THEN

DBMS_OUTPUT.PUT_LINE('VALUE_ERROR volt.');

DBMS_OUTPUT.PUT_LINE(s); -- 'Almafa' END;

-- A RETURN utasítás hatására is befejeződik a blokk működése.

-- Ilyenkor az összes tartalmazó blokk működése is befejeződik!

BEGIN

RETURN; -- A kulso címkéjű blokk működése is befejeződik.

-- Ide soha nem kerülhet a vezérlés.

DBMS_OUTPUT.PUT_LINE('Sikertelen RETURN 1. ?!');

END;

-- És ide sem kerülhet a vezérlés.

DBMS_OUTPUT.PUT_LINE('Sikertelen RETURN 2. ?!');

END;

/

Az eredmény:

SQL> @blokk hal

Elhallgató fejhallgató Almafa

VALUE_ERROR volt.

Almafa

A PL/SQL eljárás sikeresen befejeződött.

2. Alprogramok

Az alprogramok (mint minden procedurális nyelvben) a PL/SQL nyelvben is a procedurális absztrakció, az újrafelhasználhatóság, a modularitás és a karbantarthatóság eszközei. Az alprogramok paraméterezhetők és az

Programegységek

alprogramok hívhatók (aktivizálhatók) a felhasználás helyén. A PL/SQL alprogramjai alapértelmezés szerint rekurzívan hívhatók.

Az alprogramoknak két fő része van: a specifikáció és a törzs. Az alprogram felépítése ennek megfelelően a következő:

specifikáció {IS|AS}

[deklarációk]

BEGIN utasítás [utasítás]…

[EXCEPTION kivételkezelő]

END [név];

Láthatjuk, hogy az alprogram törzse a DECLARE alapszótól eltekintve megegyezik egy címke nélküli blokkal.

Az ott elmondottak érvényesek itt is.

Kétféle alprogram van: eljárás és függvény. Az eljárás valamilyen tevékenységet hajt végre, a függvény pedig egy adott értéket határoz meg.

Eljárás

Az eljárás specifikációjának alakja az alábbi:

PROCEDURE név[(formális_paraméter[,formális_paraméter]…)]

A név az eljárás neve, amelyre a hívásnál hivatkozunk. A név után az opcionális formálisparaméter-lista áll. Egy formális_paraméter formája:

név [{IN|{OUT|IN OUT} [NOCOPY]}] típus [{:=|DEFAULT}kifejezés]

A formális paraméter neve után a paraméterátadás módját lehet megadni: IN esetén érték szerinti, OUT esetén eredmény szerinti, IN OUT esetén érték-eredmény szerinti a paraméterátadás. Ha nem adjuk meg, akkor az IN alapértelmezett.

Az alprogram törzsében az IN módú paraméter nevesített konstansként, az OUT módú változóként, az IN OUT módú inicializált változóként kezelhető. Tehát az IN módú paraméternek nem adható érték.

Az OUT módú formális paraméter automatikus kezdőértéke NULL, tehát típusa nem lehet eleve NOT NULL megszorítással rendelkező altípus (például NATURALN).

IN mód esetén az aktuális paraméter kifejezés, OUT és IN OUT esetén változó lehet.

Az Oracle alaphelyzetben az OUT és IN OUT esetén a paraméterátadást értékmásolással oldja meg, azonban IN esetén nincs értékmásolás, itt a formális paraméter referencia típusú és csak az aktuális paraméter értékének a címét kapja meg. Ez azonban nem cím szerinti paraméterátadás, mert az aktuális paraméter értéke nem írható felül.

Ha azt szeretnénk, hogy az OUT és az IN OUT esetben se legyen értékmásolás, akkor adjuk meg a NOCOPY opciót. Ez egy fordítói ajánlás (hint), amelyet a fordító vagy figyelembe vesz, vagy nem. Bővebb információt ezzel kapcsolatban a [19] dokumentációban talál az Olvasó.

A típus a változó deklarációjánál megismert típusmegadás valamelyike lehet. A típus megadása nem tartalmazhat korlátozásokat, azaz hossz-, pontosság- és skálainformációkat, valamint nem szerepelhet a NOT NULL előírás sem. Korlátozott típus így csak programozói altípus vagy %TYPE segítségével adható meg.

1. példa DECLARE

Programegységek

-- Hibás paramétertípus, nem lehet korlátozást megadni PROCEDURE proc1(p_nev VARCHAR2(100) NOT NULL) …

-- Viszont mégis van rá mód programozói altípus segítségével SUBTYPE t_nev IS VARCHAR2(100) NOT NULL;

PROCEDURE proc2(p_nev t_nev) …

A := vagy DEFAULT IN módú formális paramétereknek kezdőértéket ad a kifejezés segítségével.

Az eljárást utasításszerűen tudjuk meghívni. Tehát eljáráshívás a programban mindenütt szerepelhet, ahol végrehajtható utasítás állhat. A hívás formája: név és aktuális paraméterlista.

Az eljárás befejeződik, ha elfogynak a végrehajtható utasításai, vagy pedig a RETURN utasítás hajtódik végre, amelynek alakja:

RETURN;

Ekkor a vezérlés visszatér a hívást követő utasításra. A RETURN utasítás ezen alakja használható blokk befejeztetésére is.

Eljárás nem fejeztethető be GOTO utasítással.

2. példa (Különböző paraméterátadási módok)

In document PL/SQL programozás (Pldal 76-80)