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.
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
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
s NUMBER; -- 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;
<<ki>>
DBMS_OUTPUT.PUT_LINE(s); -- 'Almafa'
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;
/
SQL> @blokk -- blokk.sql futtatása
/* Az eredmény:
hal
Elhallgató fejhallgató
Almafa
VALUE_ERROR volt.
Almafa
A PL/SQL eljárás sikeresen befejeződött.
*/