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:

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.
*/