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 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
-- 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)
DECLARE
v_Szam Number;
PROCEDURE inp(p_In IN NUMBER) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('in:' || p_In);
/* Az értékadás nem megengedett,
az IN módú paraméter nevesített konstansként viselkedik a törzsben,
ezért a következő utasítás fordítási hibát eredményezne: */
-- p_In := 0;
END inp;
PROCEDURE outp(p_Out OUT NUMBER) IS
BEGIN
/* Az OUT módú paraméter értékére lehet hivatkozni.
Kezdeti értéke azonban NULL. */
DBMS_OUTPUT.PUT_LINE('out:' || NVL(p_Out, -1));
p_Out := 20;
END outp;
PROCEDURE inoutp(p_Inout IN OUT NUMBER) IS
BEGIN
/* Az IN OUT módú paraméter értékére lehet hivatkozni.
Kezdeti értéke az aktuális paraméter értéke lesz. */
DBMS_OUTPUT.PUT_LINE('inout:' || p_Inout);
p_Inout := 30;
END inoutp;
PROCEDURE outp_kivetel(p_Out IN OUT NUMBER) IS
BEGIN
/* Az OUT és az IN OUT módú paraméter értéke csak az alprogram
sikeres lefutása esetén kerül vissza az aktuális paraméterbe.
Kezeletlen kivétel esetén nem. */
p_Out := 40;
DBMS_OUTPUT.PUT_LINE('kivétel előtt:' || p_Out);
RAISE VALUE_ERROR;
END outp_kivetel;
BEGIN
v_Szam := 10;
DBMS_OUTPUT.PUT_LINE('1:' || v_Szam);
inp(v_Szam);
inp(v_Szam + 1000); -- tetszőleges kifejezés lehet IN módú paraméter
DBMS_OUTPUT.PUT_LINE('2:' || v_Szam);
outp(v_Szam);
/* outp és inoutp paramétere csak változó lehet, ezért
a következő utasítás fordítási hibát eredményezne: */
-- outp(v_Szam + 1000);
DBMS_OUTPUT.PUT_LINE('3:' || v_Szam);
inoutp(v_Szam);
/* A következő utasítás is fordítási hibát eredményezne: */
-- inoutp(v_Szam + 1000);
DBMS_OUTPUT.PUT_LINE('4:' || v_Szam);
outp_kivetel(v_Szam);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('kivételkezelőben:' || v_Szam);
END;
/
/*
Eredmény:
1:10
in:10
in:1010
2:10
out:-1
3:20
inout:20
4:30
kivétel előtt:40
kivételkezelőben:30
A PL/SQL eljárás sikeresen befejeződött.
*/
3. példa (Eljárás használata)
/* A következőkben megadunk egy eljárást, amely adminisztrálja
egy könyv kölcsönzését. A kölcsönzés sikeres, ha van szabad példány
a könyvből és a felhasználó még kölcsönözhet könyvet. Egyébként a
kölcsönzés nem sikeres és a hiba okát kiírjuk.
Az eljárás használatát a tartalmazó blokk demonstrálja. */
DECLARE
PROCEDURE kolcsonoz(
p_Ugyfel_id ugyfel.id%TYPE,
p_Konyv_id konyv.id%TYPE,
p_Megjegyzes kolcsonzes.megjegyzes%TYPE
) IS
-- A könyvből ennyi szabad példány van.
v_Szabad konyv.szabad%TYPE;
-- Az ügyfélnél levő könyvek száma
v_Kolcsonzott PLS_INTEGER;
-- Az ügyfél által maximum kölcsönözhető könyvek száma
v_Max_konyv ugyfel.max_konyv%TYPE;
v_Datum DATE;
BEGIN
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE('Kölcsönzés - ügyfél id: ' || p_Ugyfel_id
|| ', könyv id: ' || p_Konyv_id || '.');
-- Van-e szabad példány a könyvből?
SELECT szabad
INTO v_Szabad
FROM konyv
WHERE id = p_Konyv_id;
IF v_Szabad = 0 THEN
DBMS_OUTPUT.PUT_LINE('Hiba! A könyv minden példánya ki van kölcsönözve.');
RETURN;
END IF;
-- Kölcsönözhet még az ügyfél könyvet?
SELECT COUNT(1)
INTO v_Kolcsonzott
FROM TABLE(SELECT konyvek
FROM ugyfel
WHERE id = p_Ugyfel_id);
SELECT max_konyv
INTO v_Max_konyv
FROM ugyfel
WHERE id = p_Ugyfel_id;
IF v_Max_konyv <= v_Kolcsonzott THEN
DBMS_OUTPUT.PUT_LINE('Hiba! Az ügyfél nem kölcsönözhet több könyvet.');
RETURN;
END IF;
-- A kölcsönzésnek nincs akadálya
v_Datum := SYSDATE;
UPDATE konyv
SET szabad = szabad - 1
WHERE id = p_Konyv_id;
INSERT INTO kolcsonzes
VALUES (p_Ugyfel_id, p_Konyv_id, v_Datum, 0, p_Megjegyzes);
INSERT INTO TABLE(SELECT konyvek
FROM ugyfel
WHERE id = p_Ugyfel_id)
VALUES (p_Konyv_id, v_Datum);
DBMS_OUTPUT.PUT_LINE('Sikeres kölcsönzés.');
END kolcsonoz;
BEGIN
/* Tóth László (20) kölcsönzi a 'Java - start!' című könyvet (25). */
kolcsonoz(20, 25, NULL);
/* József István (15) kölcsönzi a 'A teljesség felé' című könyvet (10).
Nem sikerül, mert az ügyfél már a maximális számú könyvet kölcsönzi. */
kolcsonoz(15, 10, NULL);
/* Komor Ágnes (30) kölcsönzi a 'A critical introduction...' című könyvet (35).
Nem sikerül, mert a könyvből már nincs szabad példány. */
kolcsonoz(30, 35, NULL);
END;
/
/*
Eredmény:
Kölcsönzés - ügyfél id: 20, könyv id: 25.
Sikeres kölcsönzés.
Kölcsönzés - ügyfél id: 15, könyv id: 10.
Hiba! Az ügyfél nem kölcsönözhet több könyvet.
Kölcsönzés - ügyfél id: 30, könyv id: 35.
Hiba! A könyv minden példánya ki van kölcsönözve.
A PL/SQL eljárás sikeresen befejeződött.
*/
4. példa (Példa a NOCOPY használatára)
DECLARE
v_lista T_Konyvek;
t0 TIMESTAMP;
t1 TIMESTAMP;
t2 TIMESTAMP;
t3 TIMESTAMP;
t4 TIMESTAMP;
PROCEDURE ido(t TIMESTAMP) IS
BEGIN
DBMS_OUTPUT.PUT_LINE(SUBSTR(TO_CHAR(t, 'SS.FF'), 1, 6));
/* Az alapértelmezett átadási mód IN esetén */
END;
PROCEDURE inp(p T_Konyvek) IS
BEGIN
NULL;
END;
/* IN OUT NOCOPY nélkül */
PROCEDURE inoutp(p IN OUT T_Konyvek) IS
BEGIN
NULL;
END;
/* IN OUT NOCOPY mellett */
PROCEDURE inoutp_nocopy(p IN OUT NOCOPY T_Konyvek) IS
BEGIN
NULL;
END;
BEGIN
/* Feltöltjük a nagyméretű változót adatokkal. */
t0 := SYSTIMESTAMP;
v_lista := T_Konyvek();
FOR i IN 1..10000
LOOP
v_lista.EXTEND;
v_lista(i) := T_Tetel(1, '00-JAN. -01');
END LOOP;
/* Rendre átadjuk a nagyméretű változót. */
t1 := SYSTIMESTAMP;
inp(v_lista);
t2 := SYSTIMESTAMP;
inoutp(v_lista);
t3 := SYSTIMESTAMP;
inoutp_nocopy(v_lista);
t4 := SYSTIMESTAMP;
ido(t0);
DBMS_OUTPUT.PUT_LINE('inicializálás');
ido(t1);
DBMS_OUTPUT.PUT_LINE('inp');
ido(t2);
DBMS_OUTPUT.PUT_LINE('inoutp');
ido(t3);
DBMS_OUTPUT.PUT_LINE('inoutp_nocopy');
ido(t4);
END;
/
/* Egy eredmény: (feltéve, hogy a NOCOPY érvényben van)
16.422
inicializálás
16.458
inp
16.458
inoutp
16.482
inoutp_nocopy
16.482
A PL/SQL eljárás sikeresen befejeződött.
*/
5. példa (Példa a NOCOPY használatára)
DECLARE
v_Szam NUMBER;
/* OUT NOCOPY nélkül */
PROCEDURE outp(p OUT NUMBER) IS
BEGIN
p := 10;
RAISE VALUE_ERROR; -- kivétel
END outp;
/* OUT NOCOPY mellett */
PROCEDURE outp_nocopy(p OUT NOCOPY NUMBER) IS
BEGIN
p := 10;
RAISE VALUE_ERROR; -- kivétel
END outp_nocopy;
BEGIN
v_Szam := 0;
BEGIN
outp(v_Szam);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('1: ' || v_Szam);
END;
v_Szam := 0;
BEGIN
outp_nocopy(v_Szam);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('2: ' || v_Szam);
END;
END;
/
/* Eredmény: (feltéve, hogy a NOCOPY érvényben van)
1: 0
2: 10
A PL/SQL eljárás sikeresen befejeződött.
Magyarázat:
Az eljáráshívásokban kivétel következik be. Így egyik eljárás sem sikeres.
outp hívása esetén így elmarad a formális paraméternek az aktuálisba
történő másolása.
outp_nocopy hívásakor azonban az aktuális paraméter megegyezik a formálissal,
így az értékadás eredményes lesz az aktuális paraméterre nézve.
*/
6. példa Példa a NOCOPY használatára)
DECLARE
v_Szam NUMBER;
/*
Eredmény szerinti paraméterátadás.
Az aktuális paraméter az alprogram befejeztével
értékül kapja a formális paraméter értékét.
*/
PROCEDURE valtoztat1(p OUT NUMBER) IS
BEGIN
p := 10;
v_Szam := 5;
END valtoztat1;
/*
Referencia szerinti paraméterátadás (feltéve, hogy a NOCOPY érvényben van).
Az aktuális paraméter megegyezik a formálissal.
Nincs értékadás az alprogram befejezésekor.
*/
PROCEDURE valtoztat2(p OUT NOCOPY NUMBER) IS
BEGIN
p := 10;
v_Szam := 5;
END valtoztat2;
BEGIN
v_Szam := NULL;
valtoztat1(v_Szam); -- Az alprogram végén v_Szam p értékét kapja meg
DBMS_OUTPUT.PUT_LINE('eredmény szerint: ' || v_Szam);
v_Szam := NULL;
valtoztat2(v_Szam); -- Az alprogramban v_Szam és p megegyezik
DBMS_OUTPUT.PUT_LINE('referencia szerint: ' || v_Szam);
END;
/
/*
Eredmény:
eredmény szerint: 10
referencia szerint: 5
*/
7. példa (Példa a NOCOPY használatára)
DECLARE
v_Szam NUMBER;
/*
A három paraméter átadásának módja (feltéve, hogy a NOCOPY érvényben van):
p1 - referencia szerinti
p2 – érték-eredmény szerinti
p3 - referencia szerinti
*/
PROCEDURE elj(
p1 IN NUMBER,
p2 IN OUT NUMBER,
p3 IN OUT NOCOPY NUMBER
) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('1: '||v_Szam||' '||p1||' '||p2||' '||p3);
p2 := 20;
DBMS_OUTPUT.PUT_LINE('2: '||v_Szam||' '||p1||' '||p2||' '||p3);
p3 := 30;
DBMS_OUTPUT.PUT_LINE('3: '||v_Szam||' '||p1||' '||p2||' '||p3);
END elj;
BEGIN
DBMS_OUTPUT.PUT_LINE(' v_Szam p1 p2 p3');
DBMS_OUTPUT.PUT_LINE('-- ------ -- -- --');
v_Szam := 10;
elj(v_Szam, v_Szam, v_Szam);
DBMS_OUTPUT.PUT_LINE('4: ' || v_Szam);
END;
/
/*
Eredmény:
v_Szam p1 p2 p3
-- ------ -- -- --
1: 10 10 10 10
2: 10 10 20 10
3: 30 30 20 30
4: 20
Magyarázat:
Az eljárás hívásakor p1, p3 és v_Szam ugyanazt a szám objektumot jelölik,
p2 azonban nem. Ezért p2 := 20; értékadás nem változtatja meg p1-et, így
p3-at és v_Szam-ot sem közvetlenül. A p3 := 30; értékadás viszont
megváltoztatja p1-et, azaz p3-at, azaz v_Szam-ot is 30-ra.
Az eljárás befejeztével v_Szam aktuális paraméter megkapja p2 formális
paraméter értékét, az értékeredmény átadási mód miatt. Így v_Szam értéke 20 lesz.
A példa azt is igazolja, hogy p1 is referencia szerint kerül átadásra.
*/
Függvény
A függvény specifikációjának alakja:
FUNCTION név [(formális_paraméter[,formális_paraméter]…)]
RETURN típus
A formálisparaméter-lista szintaktikailag és szemantikailag megegyezik az eljárás formálisparaméter-listájával.
A RETURN alapszó után a típus a függvény visszatérési értékének a típusát határozza meg.
Egy függvényt meghívni kifejezésben lehet. A hívás formája: név és aktuálisparaméterlista.
A függvény törzsében legalább egy RETURN utasításnak szerepelnie kell, különben a PROGRAM_ERROR kivétel váltódik ki működése közben. A függvényben használt RETURN utasítás a visszatérési értéket is meghatározza. Alakja:
RETURN [(]kifejezés[)];
A visszatérési érték a kifejezés értéke lesz, az érték a függvény nevéhez rendelődik, az közvetíti vissza a hívás helyére.
A függvény mellékhatásának hívjuk azt a jelenséget, amikor a függvény megváltoztatja a paramétereit vagy a környezetét (a globális változóit). A függvény feladata a visszatérési érték meghatározása, ezért a mellékhatás akár káros is lehet. Éppen ezért kerüljük az OUT és IN OUT módú paraméterek és a globális változók használatát.
8. példa
DECLARE
v_Datum DATE;
i number := 1;
/* Megnöveli p_Datum-ot a második p_Ido-vel, aminek a mértékegységét p_Egyseg
tartalmazza. Ezek értéke 'perc', 'óra', 'nap', 'hónap' egyike lehet.
Ha hibás a mértékegység, akkor az eredeti dátumot kapjuk vissza. */
FUNCTION hozzaad( p_Datum DATE, p_Ido NUMBER, p_Egyseg VARCHAR2) RETURN DATE IS rv DATE;
BEGIN
CASE p_Egyseg
WHEN 'perc' THEN
rv := p_Datum + p_Ido/(24*60);
WHEN 'óra' THEN
rv := p_Datum + p_Ido/24;
WHEN 'nap' THEN
rv := p_Datum + p_Ido;
WHEN 'hónap' THEN
rv := ADD_MONTHS(p_Datum, p_Ido);
ELSE
rv := p_Datum;
END CASE;
RETURN rv;
END hozzaad;
PROCEDURE kiir(p_Datum DATE) IS
BEGIN
DBMS_OUTPUT.PUT_LINE(i || ': ' || TO_CHAR(p_Datum, 'YYYY-MON-DD HH24:MI:SS'));
END kiir;
BEGIN
v_Datum := TO_DATE('2006-MÁJ.-01 20:00:00', 'YYYY-MON-DD HH24:MI:SS');
i:=1;
kiir(v_Datum); -- 1
DBMS_OUTPUT.NEW_LINE;
kiir(hozzaad(v_Datum, 5, 'perc')); -- 2
kiir(hozzaad(v_Datum, 1.25, 'óra')); -- 3
kiir(hozzaad(v_Datum, -7, 'nap')); -- 4
kiir(hozzaad(v_Datum, -8, 'hónap')); -- 5
END;
/
/*
Eredmény:
1: 2006-MÁJ.-01 20:00:00
2: 2006-MÁJ.-01 20:05:00
3: 2006-MÁJ.-01 21:15:00
4: 2006-ÁPR.-24 20:00:00
5: 2005-SZEPT.-01 20:00:00
A PL/SQL eljárás sikeresen befejeződött.
*/
9. példa
DECLARE
i NUMBER;
j NUMBER;
k NUMBER;
/* Ennek a függvénynek van pár mellékhatása. */
FUNCTION mellekhatas(
p1 NUMBER,
/* OUT és IN OUT módú paraméterek nem lehetnek egy tiszta függvényben.
Minden értéket a visszatérési értékben kellene visszaadni.
Ez rekorddal megtehető, amennyiben tényleg szükséges. */
p2 OUT NUMBER,
p3 IN OUT NUMBER,
p4 IN OUT NUMBER
) RETURN NUMBER IS
BEGIN
i := 10; -- globális változó megváltoztatása
DBMS_OUTPUT.PUT_LINE('Egy tiszta függvény nem ír a kimenetére sem.');
p2 := 20;
p3 := 30;
p4 := p3;
RETURN 50;
END;
BEGIN
i := 0;
j := mellekhatas(j, j, j, k);
/* Mennyi most i, j és k értéke? */
DBMS_OUTPUT.PUT_LINE('i= ' || i);
DBMS_OUTPUT.PUT_LINE('j= ' || j);
DBMS_OUTPUT.PUT_LINE('k= ' || k);
END;
/
/*
Eredmény:
Egy tiszta függvény nem ír a kimenetére sem.
i= 10
j= 50
k= 30
A PL/SQL eljárás sikeresen befejeződött.
*/
Formális és aktuális paraméterek
Az alprogramok közötti kommunikáció, információcsere paraméterek segítségével történik. Egy adott formálisparaméter-listával rendelkező alprogram akárhány aktuális paraméterlistával meghívható.
Az aktuális paraméter típusának a formális paraméter típusával kompatibilisnek kell lennie.
A formális paraméterek és az aktuális paraméterek egymáshoz rendelése történhet pozíció vagy név szerint. A pozíció szerinti egymáshoz rendelés azt jelenti, hogy a formális és aktuális paraméterek sorrendje a döntő (sorrendi kötés). Az első formális paraméterhez az első aktuális paraméter, a másodikhoz a második stb. rendelődik hozzá.
A név szerinti egymáshoz rendelésnél (név szerinti kötés) az aktuálisparaméter-listán a formális paraméterek sorrendjétől függetlenül, tetszőleges sorrendben felsoroljuk a formális paraméterek nevét, majd a => jelkombináció után megadjuk a megfelelő aktuális paramétert.
A kétfajta megfeleltetés keverhető is, de lényeges, hogy elöl mindig a pozicionális paraméterek állnak, és őket követik a név szerinti kötéssel rendelkezők.
A PL/SQL-ben a programozó csak fix paraméterű alprogramokat tud írni (szemben például a C nyelvvel, ahol változó paraméterszámú függvények is létrehozhatók). Az alprogramok hívásánál az aktuális paraméterek száma kisebb vagy egyenlő lehet, mint a formális paraméterek száma. Ez az IN módú paramétereknek adott kezdőértékek kezelésétől függ. Egy olyan formális paraméterhez, amelynek van kezdőértéke, nem szükséges megadnunk aktuális paramétert. Ha megadunk, akkor az inicializálás az aktuális paraméter értékével, ha nem adunk meg, akkor a formálisparaméter-listán szereplő kezdőértékkel történik.
A PL/SQL megengedi lokális és csomagbeli alprogramnevek túlterhelését. Az ilyen alprogramoknál a név azonos, de a formális paraméterek száma, típusa vagy sorrendje eltérő kell legyen. Ekkor a fordító az aktuálisparaméter-lista alapján választja ki a hívásnál a megfelelő törzset.
10. példa
DECLARE
v_Datum DATE;
/* Visszaadja p_Datumot a p_Format formátumban, ha hiányzik valamelyik,
akkor az alapértelmezett kezdőértékkel dolgozik a függvény */
FUNCTION to_char2(
p_Datum DATE DEFAULT SYSDATE,
p_Format VARCHAR2 DEFAULT 'YYYY-MON-DD HH24:MI:SS'
) RETURN VARCHAR2 IS
BEGIN
return TO_CHAR(p_Datum, p_Format);
END to_char2;
BEGIN
v_Datum := TO_DATE('2006-ÁPR. -10 20:00:00', 'YYYY-MON-DD HH24:MI:SS');
/* sorrendi kötés */
DBMS_OUTPUT.PUT_LINE('1: ' || to_char2(v_Datum, 'YYYY-MON-DD'));
/* név szerinti kötés */
DBMS_OUTPUT.PUT_LINE('2: ' || to_char2(p_Format => 'YYYY-MON-DD',
p_Datum => v_Datum));
/* név szerinti kötés és paraméter hiánya */
DBMS_OUTPUT.PUT_LINE('3: ' || to_char2(p_Format => 'YYYY-MON-DD'));
/* mindkét kötés keverve */
DBMS_OUTPUT.PUT_LINE('4: ' || to_char2(v_Datum, p_Format => 'YYYY-MON-DD'));
/* mindkét paraméter hiánya */
DBMS_OUTPUT.PUT_LINE('5: ' || to_char2);
END;
/
/*
Eredmény (ha az aktuális dátum 2006-JÚN.-19 17:39:16):
1: 2006-ÁPR. -10
2: 2006-ÁPR. -10
3: 2006-JÚN. -19
4: 2006-ÁPR. -10
5: 2006-JÚN. -19 17:39:16
A PL/SQL eljárás sikeresen befejeződött.
*/
11. példa (Alprogram nevének túlterhelése)
DECLARE
v_Marad NUMBER;
/* Megadja, hogy a p_Ugyfel_id azonosítójú ügyfél még
még hány könyvet kölcsönözhet. */
PROCEDURE marad(p_Ugyfel_id ugyfel.id%TYPE, p_Kolcsonozhet OUT NUMBER) IS
BEGIN
SELECT max_konyv - db
INTO p_Kolcsonozhet
FROM
(SELECT max_konyv FROM ugyfel WHERE id = p_Ugyfel_id),
(SELECT COUNT(1) AS db FROM kolcsonzes WHERE kolcsonzo = p_Ugyfel_id);
END marad;
/* Megadja, hogy a p_Ugyfel_nev nevű ügyfél még hány könyvet kölcsönözhet. */
PROCEDURE marad( p_Ugyfel_nev ugyfel.nev%TYPE, p_Kolcsonozhet OUT NUMBER) IS
v_Id ugyfel.id%TYPE;
BEGIN
SELECT id
INTO v_Id
FROM ugyfel
WHERE nev = p_Ugyfel_nev;
marad(v_Id, p_Kolcsonozhet);
END marad;
BEGIN
/* József István (15) */
marad(15, v_Marad);
DBMS_OUTPUT.PUT_LINE('1: ' || v_Marad);
/* Komor Ágnes (30) */
marad('Komor Ágnes', v_Marad);
DBMS_OUTPUT.PUT_LINE('2: ' || v_Marad);
END;
/
/* Eredmény:
1: 0
2: 3
A PL/SQL eljárás sikeresen befejeződött.
*/