Elágaztató utasítások

Az elágaztató utasítások segítségével a programba olyan szerkezetek építhetők be, amelyek bizonyos tevékenységek alternatív végrehajtását teszik lehetővé.

A feltételes utasítás egymást kölcsönösen kizáró tevékenységek közül egy feltételsorozat alapján választ ki egyet végrehajtásra, vagy esetleg egyet sem választ. Alakja:

IF feltétel THEN utasítás [utasítás]…

[ELSIF feltétel THEN utasítás [utasítás]…]…

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

END IF;

A feltételes utasításnak három formája van: IF-THEN, IF-THEN-ELSE és IF-THEN-ELSIF.

A legegyszerűbb alak esetén a tevékenységet a THEN és az END IF alapszavak közé zárt utasítássorozat írja le. Ezek akkor hajtódnak végre, ha a feltétel értéke igaz. Hamis és NULL feltételértékek mellett az IF utasítás nem csinál semmit, tehát hatása megegyezik egy üres utasításéval.

Az IF-THEN-ELSE alak esetén az egyik tevékenységet a THEN és ELSE közötti, a másikat az ELSE és END IF közötti utasítássorozat adja. Ha a feltétel igaz, akkor a THEN utáni, ha hamis vagy NULL, akkor az ELSE utáni utasítássorozat hajtódik végre.

A harmadik alak egy feltételsorozatot tartalmaz. Ez a feltételsorozat a felírás sorrendjében értékelődik ki. Ha valamelyik igaz értékű, akkor az utána következő THEN-t követő utasítássorozat hajtódik végre. Ha minden feltétel hamis vagy NULL értékű, akkor az ELSE alapszót követő utasítássorozatra kerül a vezérlés, ha nincs ELSE rész, akkor ez egy üres utasítás.

Az IF utasítás esetén bármely tevékenység végrehajtása után (ha nem volt az utasítások között GOTO) a program az IF-et követő utasításon folytatódik.

A THEN és ELSE után álló utasítások között lehet újabb IF utasítás, az egymásba skatulyázás mélysége tetszőleges.

Megjegzés: Az alábbi programban több hiba is található!!

Példák

DECLARE
  v_Nagyobb NUMBER;
  x NUMBER;
  y NUMBER;
  z NUMBER;
BEGIN
  .
  .
  .
  v_Nagyobb := x;
  IF x < y THEN
    v_Nagyobb := y;
  END IF;
  .
  .
  .
  v_Nagyobb := x;
  IF x < y THEN
    v_Nagyobb := y;
  ELSE
    DBMS_OUTPUT.PUT_LINE('x tényleg nem kisebb y-nál.');
  END IF;
  .
  .
  .
  IF x < y THEN
    v_Nagyobb := y;
  ELSE
    v_Nagyobb := x;
  END IF;
  .
  .
  .
  IF x > y THEN
    IF x > z THEN
      v_Nagyobb := x;
    ELSE
      v_Nagyobb := z;
  ELSE
    IF y > z THEN
        v_Nagyobb := y;
    ELSE
        v_Nagyobb := z;
    END IF;
    .
    .
    .
    IF x < y THEN
      DBMS_OUTPUT.PUT_LINE('x kisebb, mint y');
      v_Nagyobb = x;
    ELSIF x > y THEN
      DBMS_OUTPUT.PUT_LINE('x nagyobb, mint y');
      v_Nagyobb = y;
    ELSE
      DBMS_OUTPUT.PUT_LINE('x és y egyenlők');
      v_Nagyobb = x; -- lehetne y is
    END IF;
  .
  .
  .
END;

A CASE egy olyan elágaztató utasítás, ahol az egymást kölcsönösen kizáró tevékenységek közül egy kifejezés értékei, vagy feltételek teljesülése szerint lehet választani. Az utasítás alakja:

CASE [szelektor_kifejezés]
  WHEN {kifejezés | feltétel} THEN utasítás [utasítás]…
  [WHEN {kifejezés | feltétel} THEN utasítás [utasítás]…]…
  [ELSE utasítás [utasítás]…]
END CASE;

Ha a CASE utasítás címkézett, az adott címke az END CASE után feltüntethető.

Tehát egy CASE utasítás tetszőleges számú WHEN ágból és egy opcionális ELSE ágból áll. Ha a szelektor_kifejezés szerepel, akkor a WHEN ágakban kifejezés áll, ha nem szerepel, akkor feltétel.

Működése a következő:

Ha szerepel szelektor_kifejezés, akkor ez kiértékelődik, majd az értéke a felírás sorrendjében hasonlításra kerül a WHEN ágak kifejezéseinek értékeivel. Ha megegyezik valamelyikkel, akkor az adott ágban a THEN után megadott utasítássorozat hajtódik végre, és ha nincs GOTO, akkor a működés folytatódik a CASE utasítást követő utasításon.

Ha a szelektor_kifejezés értéke nem egyezik meg egyetlen kifejezés értékével sem és van ELSE ág, akkor végrehajtódnak az abban megadott utasítások, és ha nincs GOTO, akkor a működés folytatódik a CASE utasítást követő utasításon. Ha viszont nincs ELSE ág, akkor a CASE_NOT_FOUND kivétel váltódik ki.

Ha a CASE alapszó után nincs megadva szelektor_kifejezés, akkor a felírás sorrendjében sorra kiértékelődnek a feltételek és amelyik igaz értéket vesz fel, annak a WHEN ága kerül kiválasztásra. A szemantika a továbbiakban azonos a fent leírtakkal.

Példák

/* Case 1 - szelektor_kifejezés van, az első egyező értékű ág fut le,
az ágakban tetszőleges értékű kifejezés szerepelhet.
*/
DECLARE
   v_Allat VARCHAR2(10);
BEGIN
  v_Allat := 'hal';
  CASE v_Allat || 'maz'
    WHEN 'halló' THEN
      DBMS_OUTPUT.PUT_LINE('A halló nem is állat.');
    WHEN SUBSTR('halmazelmélet', 1, 6) THEN
      DBMS_OUTPUT.PUT_LINE('A halmaz sem állat.');
    WHEN 'halmaz' THEN
      DBMS_OUTPUT.PUT_LINE('Ez már nem fut le.');
    ELSE
      DBMS_OUTPUT.PUT_LINE('Most ez sem fut le.');
  END CASE;
END;
/

/* Case 2 - szelektor_kifejezés van, nincs egyező ág, nincs ELSE */
BEGIN
  CASE 2
    WHEN 1 THEN
      DBMS_OUTPUT.PUT_LINE('2 = 1');
    WHEN 1+2 THEN
      DBMS_OUTPUT.PUT_LINE('2 = 1 + 2 = ' || (1+2));
  END CASE;
  -- kivétel: ORA-06592, azaz CASE_NOT_FOUND
END;
/

/* Case 3 - A case utasítás cimkézhető. */
BEGIN
  -- A case ágai cimkézhetők
  <<elso_elagazas>>
  CASE 1
    WHEN 1 THEN
      <<masodik_elagazas>>
    CASE 2
      WHEN 2 THEN
        DBMS_OUTPUT.PUT_LINE('Megtaláltuk.');
    END CASE masodik_elagazas;
  END CASE elso_elagazas;
END;
/

/* Case 4 - Nincs szelektor_kifejezés, az ágakban feltétel szerepel.*/
DECLARE
  v_Szam NUMBER;
BEGIN
  v_Szam := 10;
  CASE
    WHEN v_Szam MOD 2 = 0 THEN
      DBMS_OUTPUT.PUT_LINE('Páros.');
    WHEN v_Szam < 5 THEN
      DBMS_OUTPUT.PUT_LINE('Kisebb 5-nél.');
    WHEN v_Szam > 5 THEN
      DBMS_OUTPUT.PUT_LINE('Nagyobb 5-nél.');
    ELSE
      DBMS_OUTPUT.PUT_LINE('Ez csak az 5 lehet.');
  END CASE;
END;
/