4 Kontrollstrukturen in PL/SQL

Werbung
4
Kontrollstrukturen in PL/SQL
4.1
4.2
Bedingte Anweisungen................................................................... 4-2
4.1.1 Die IF-THEN-Anweisung.................................................... 4-2
4.1.2 Die IF-THEN-ELSE-Anweisung.......................................... 4-4
4.1.3 Die IF-THEN-ELSIF-Anweisung........................................ 4-4
4.1.4 Die CASE-Anweisung ......................................................... 4-6
Schleifen in PL/SQL ..................................................................... 4-10
4.2.1 Die Basisschleife ............................................................. 4-12
4.2.2 Die FOR-Schleife .............................................................. 4-14
4.2.3 Die WHILE-Schleife.......................................................... 4-16
4.2.4 Verschachtelte Schleifen ................................................. 4-18
1.2.066 / 4053
4-1
4
Kontrollstrukturen in PL/SQL
4
Kontrollstrukturen in PL/SQL
4.1
Bedingte Anweisungen
Mit Hilfe von ‘IF‘-Konstrukten lassen sich Bedingungen festlegen, die
erfüllt (’TRUE‘) sein müssen, damit die nachfolgende(n) Anweisung(en)
ausgeführt werden. Ist das Ergebnis einer Bedingung FALSE oder
NULL (z.B., wenn ein Wert in einem Vergleich unbekannt ist), so werden die nachfolgenden Anweisungen nicht ausgeführt.
4.1.1
Die IF-THEN-Anweisung
Die ‘IF-THEN‘-Anweisung ist die einfachste Form der bedingten Anweisung. Sie wird wie alle IF-Konstrukte mit 'END IF' abgeschlossen. Alle
Anweisungen, die zwischen IF und END IF stehen, werden ausgeführt, wenn die Bedingung, die dem Schlüsselwort IF folgt, TRUE ist.
Syntax:
IF bedingung THEN
Anweisung;
{Anweisung;}
END IF;
Zur besseren Lesbarkeit sollte ein IF-Konstrukt in obiger Form mit eingerücktem Code geschrieben werden.
Hinweis: Achtung bei NULL-Werten! Jeder Vergleich mit NULL (außer mittels
IS NULL) ergibt NULL (und damit: Bedingung nicht erfüllt!)
Beispiel:
SELECT mgr INTO v_mgr
FROM emp WHERE empno = v_empno;
IF v_mgr != 7698 then ...
Für empno=7839 ist mgr NULL, und die Bedingung ist damit nicht erfüllt!
Alternative: z. B. IF NVL(v_mgr, 0) != 7839
oder:
4-2
IF v_mgr != 7698 OR v_mgr IS NULL
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
IF – THEN – END IF
4
ƒ Bedingte Anweisungen
ƒ durch Verwendung von IF-Konstrukten
ƒ Bedingung muss TRUE ergeben
ƒ Syntax:
IF bedingung THEN
Anweisung;
{Anweisung}
END IF
ƒ alle Anweisungen zwischen IF und END IF werden nur ausgeführt, wenn Bedingung
hinter IF TRUE ist
ƒ Vergleich mit NULL ist immer FALSE
www.unilog.integrata.de
www.unilog-integrata.de
4053 / 1.2.036
Folie 2
IF – THEN – END IF (f)
4
ƒ Beispiele:
IF SQL%FOUND THEN
v_count := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE(v_count ||
' Zeilen wurden geändert');
COMMIT;
END IF;
IF a > b THEN
v_num := v_num * a;
END IF;
IF UPPER(v_name) LIKE 'SMI%' THEN
INSERT INTO temp (name, date)
VALUES (UPPER(v_name), SYSDATE);
END IF;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 3
4-3
4
4.1.2
Kontrollstrukturen in PL/SQL
Die IF-THEN-ELSE-Anweisung
Sie ist eine Erweiterung der reinen IF-Anweisung, bei der angegeben
wird, was getan werden soll, wenn die Bedingung nicht erfüllt ist. Ist die
Bedingung erfüllt, werden alle dem THEN folgenden Anweisungen ausgeführt, die Anweisungen im ELSE-Zweig werden übersprungen. Ist die
Bedingung nicht erfüllt, werden nur die Anweisungen im ELSE-Zweig
ausgeführt.
Syntax:
IF bedingung THEN
Anweisung; {Anweisung;}
ELSE
Anweisung; {Anweisung;}
END IF;
4.1.3
Die IF-THEN-ELSIF-Anweisung
Auch hier wird in den ELSIF-Zweig abgezweigt, wenn die IFBedingung nicht erfüllt ist. Nach ELSIF wird eine andere Bedingung
angegeben, die erfüllt sein muss, damit die nachfolgenden Anweisungen ausgeführt werden. Auch hier kann zuletzt noch ein ELSE-Zweig
folgen. Der Unterschied zu zwei aufeinanderfolgenden IF-Konstrukten
liegt darin, dass der ELSE-Zweig nur erreicht wird, wenn beide Bedingungen nicht erfüllt sind.
Syntax:
IF bedingung THEN
Anweisung; {Anweisung;}
{ELSIF bedingung THEN
Anweisung; {Anweisung;}
}
[ELSE
Anweisung; {Anweisung;}
]
END IF;
Hinweis: Alle IF-Konstrukte können beliebig ineinander verschachtelt werden.
4-4
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
IF – THEN – ELSE/ELSIF – END IF
4
4
ƒ IF-THEN-ELSE Anweisung
ƒ Der ELSE-Zweig wird ausgeführt, wenn die Bedingung nicht erfüllt ist
ƒ IF-THEN-ELSIF-ELSE Anweisung
ƒ Der ELSIF-Zweig wird ausgeführt, wenn die 1. Bedingung nicht erfüllt ist, aber die
hinter ELSIF angegebene Bedingung erfüllt ist
ƒ Der ELSE- Zweig wird ausgeführt, wenn beide Bedingungen nicht erfüllt sind
www.unilog.integrata.de
www.unilog-integrata.de
4053 / 1.2.036
Folie 4
IF – THEN – ELSE/ELSIF – END IF (f)
4
ƒ Beispiele:
IF a > b THEN
v_num := v_num * a;
ELSE
v_num := v_num * b;
END IF;
SELECT job INTO v_job
FROM emp WHERE empno = v_no;
IF v_job = 'SALESMAN' THEN
UPDATE emp SET comm = comm * 1.1
WHERE empno = v_no;
ELSIF v_job = 'MANAGER' THEN
UPDATE emp SET sal = sal * 1.2
WHERE empno = v_no;
ELSIF v_job = 'PRESIDENT' THEN
NULL;
ELSE
UPDATE emp SET sal = sal * 1.5
WHERE empno = v_no;
END IF;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 5
4-5
4
4.1.4
Kontrollstrukturen in PL/SQL
Die CASE-Anweisung
Mit der CASE-Anweisung lassen sich Fallunterscheidungen mit vielen
möglichen Werten vereinfachen.
Syntax 1 (mit Selektor):
CASE variable
WHEN wert | ausdruck THEN anweisung(en);
{WHEN wert | ausdruck THEN anweisung(en);}
[ELSE anweisung(en);]
END CASE;
Syntax 2 (ohne Selektor):
CASE
WHEN bedingung1 THEN anweisung(en);
WHEN bedingung2 THEN anweisung(en);
...
[ELSE anweisung(en);]
END CASE;
Bei Syntax 1 sind auch Ausdrücke oder Funktionsaufrufe als Selektor
erlaubt. Die einzigen nicht zulässigen Datentypen sind BLOB, BFILE,
Record, Index-by-Tables, Nested Tables, VArrays und Objekttypen.
Es wird immer nur ein Zweig der Fallunterscheidung durchlaufen. Falls
keine ELSE-Klausel angegeben wird, wird implizit ergänzt: ELSE
RAISE CASE_NOT_FOUND;
CASE ist auch zulässig als Teil eines Ausdrucks in der Form (hier nur
mit Selektor gezeigt):
wert :=
CASE variable
WHEN wert1|ausdruck1 THEN ergebnis1
WHEN wert2|ausdruck2 THEN ergebnis2
....
[ELSE ergebnis;]
END;
4-6
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
CASE
4
ƒ Syntax 1 (mit Selektor):
CASE variable
WHEN wert | ausdruck THEN
anweisung(en);
{WHEN wert | ausdruck THEN
anweisung(en);}
[ELSE anweisung(en);]
END [CASE];
ƒ Syntax 2 (ohne Selektor):
CASE
WHEN bedingung THEN
anweisung(en);
{WHEN bedingung THEN
anweisung(en);}
[ELSE anweisung(en);]
END [CASE];
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 6
4-7
4
Kontrollstrukturen in PL/SQL
Wird hier kein ELSE-Zweig angegeben und trifft keiner der WHENZweige zu, so wird NULL zurückgegeben.
Beispiel:
undefine pempno
ACCEPT pempno PROMPT
'Bitte geben Sie eine Personalnr. ein (z.B. 7900): '
prompt 'Anfangsstand'
select * from emp where empno = &pempno;
prompt 'Prozedurbeginn..'
declare
V_gehaltserhoehung NUMBER :=1;
v_job
emp.job%type;
begin
SELECT job INTO v_job FROM emp
WHERE empno = &pempno;
V_gehaltserhoehung :=
CASE v_job
WHEN 'PRESIDENT' THEN 1
WHEN 'SALESMAN' THEN 1.07
WHEN 'MANAGER'
THEN 1.05
WHEN 'CLERK'
THEN 1.1
WHEN 'ANALYST'
THEN 1.04
ELSE 0
END;
UPDATE emp SET sal = sal* V_gehaltserhoehung
where empno = &pempno;
END;
/
prompt 'End-Zustand'
select * from emp where empno = &pempno
/
4-8
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
Beispiel
4
ƒ Beispiel:
SELECT job INTO v_job
FROM emp
WHERE empno = &pempno;
v_gehaltserhoehung :=
CASE v_job
WHEN 'PRESIDENT' THEN 1
WHEN 'SALESMAN' THEN 1.07
WHEN 'MANAGER'
THEN 1.05
WHEN 'CLERK'
THEN
1.1
WHEN 'ANALYST'
THEN 1.04
ELSE 0
END;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 7
4-9
4
4.2
Kontrollstrukturen in PL/SQL
Schleifen in PL/SQL
Schleifen ermöglichen es, bestimmte Teile eines PL/SQL-Blockes wiederholt durchlaufen zu lassen. Sie werden auch als LOOP-Anweisungen
bezeichnet, da sie alle das Schlüsselwort LOOP beinhalten und mit END
LOOP enden.
Die EXIT-Anweisung sorgt dafür, dass eine Schleife bedingungslos
verlassen wird, die EXIT-WHEN-Anweisung sorgt dafür, dass eine
Schleife verlassen wird, wenn die Bedingung erfüllt (TRUE) ist. EXIT
kann in einer Schleife mehrmals vorkommen.
Es werden 3 Arten von Schleifen in PL/SQL unterschieden:
– Basisschleife: unbedingte Schleife
– For-Schleife: Schleife mit Zähler
– While-Schleife: Schleife mit Bedingung
4-10
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
Schleifen in PL/SQL
4
ƒ Schleifen in PL/SQL:
ƒ ermöglichen die wiederholte Abarbeitung der in der Schleife enthaltenen Anweisung(en)
ƒ können mit EXIT [WHEN] verlassen werden
ƒ Es gibt drei Typen:
ƒ Basisschleife (LOOP)
ƒ FOR-Schleife
ƒ WHILE-Schleife
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 8
4-11
4
4.2.1
Kontrollstrukturen in PL/SQL
Die Basisschleife
Diese Schleifenart kennt weder Schleifenbedingung noch Schleifenzähler, die die Anzahl der Schleifendurchläufe begrenzen. Ohne 'EXIT
[WHEN]'-Befehl ist diese Schleife eine Endlosschleife.
Syntax:
LOOP
Anweisung;
{Anweisung;}
[EXIT [WHEN Bedingung];]
{Anweisung;}
END LOOP;
4-12
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
Basisschleife
4
ƒ ist ohne EXIT [WHEN] eine Endlosschleife
ƒ beginnt mit
endet mit
LOOP
END LOOP
ƒ Syntax der Basisschleife:
LOOP
Anweisung;
{Anweisung;}
[EXIT [WHEN Bedingung];]
{Anweisung;}
END LOOP;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 9
4-13
4
4.2.2
Kontrollstrukturen in PL/SQL
Die FOR-Schleife
Die FOR-Schleife bietet die Möglichkeit, mit Hilfe eines Schleifenzählers
die Anzahl der Schleifendurchläufe vorzugeben. Der Schleifenzähler
wird implizit (als INTEGER) deklariert, braucht also im DECLARE-Teil
nicht angegeben zu werden. Pro Schleifendurchlauf wird der Zähler automatisch um 1 erhöht bzw. erniedrigt, eine andere Schrittweite kann
nicht angegeben werden.
Innerhalb der Schleife kann der Zähler wie eine Konstante referenziert
werden, es kann ihm aber kein neuer Wert zugewiesen werden (z. B.,
um eine andere Schrittweite zu erzielen), außerhalb der Schleife ist er
nicht definiert.
Als Unter- und Obergrenze sind numerische Literale, Variablen und
Ausdrücke zulässig, solange sie als Zahlen ausgewertet werden können. Ist die Untergrenze höher als die Obergrenze, so wird die FORSchleife überhaupt nicht betreten, sind beide gleich hoch, so wird sie
einmal durchlaufen.
Syntax:
FOR zaehler IN [REVERSE] Untergrenze..Obergrenze LOOP
Anweisung;
{Anweisung;}
END LOOP;
Das Schlüsselwort REVERSE sorgt dafür, dass von der Obergrenze
nach unten gezählt wird; dennoch wird die Untergrenze vor der Obergrenze angegeben.
Beispiel:
DECLARE
v_count number;
v_job varchar2(9);
BEGIN
SELECT count(*) INTO v_count
FROM emp;
FOR i IN 1..v_count LOOP
IF mod(i, 5) = 0 THEN
DBMS_OUTPUT.PUT_LINE ( i ||
'Durchläufe absolviert');
END iF;
END LOOP;
END;
4-14
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
FOR Schleife
ƒ
ƒ
ƒ
ƒ
4
Ober- und Untergrenze geben die Anzahl der Durchläufe an
Schrittweite ist immer 1
Schleifenzähler kann innerhalb der Schleife referenziert, aber nicht verändert werden
Defaultmäßig wird hochgezählt, durch REVERSE wird heruntergezählt
ƒ Beispiel:
DECLARE
v_count number;
v_job varchar2(9);
BEGIN
SELECT count(*) INTO v_count
FROM emp;
FOR i IN 1..v_count LOOP
IF mod(i, 5) = 0 THEN
DBMS_OUTPUT.PUT_LINE ( i ||
'Durchläufe absolviert');
END iF;
END LOOP;
END;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 10
4-15
4
4.2.3
Kontrollstrukturen in PL/SQL
Die WHILE-Schleife
Bei der WHILE-Schleife wird eine Schleifenbedingung vor jedem Durchlauf der Schleife geprüft. Ist die Bedingung TRUE, so wird die Schleife
durchlaufen und an den Beginn der Schleife zurückgekehrt.
Daher steht bei einer WHILE-Schleife die Anzahl der Iterationen nicht
von vornherein fest. Die Schleife wird so lange durchlaufen, bis die Anfangsbedingung FALSE oder NULL liefert. Ist die Bedingung von vornherein FALSE (oder NULL), so wird sie die Schleife überhaupt nicht
durchlaufen, bleibt die Bedingung TRUE, so hat man eine Endlosschleife (z. B. WHILE 1 = 1).
Syntax:
WHILE Bedingung LOOP
Anweisung;
{Anweisung;}
END LOOP;
Beispiel:
DECLARE
v_min number(4);
v_found BOOLEAN := FALSE;
BEGIN
SELECT min(empno) INTO v_min FROM emp;
WHILE NOT v_found LOOP
v_min := v_min +1;
DELETE FROM emp WHERE empno = v_min;
v_found := SQL%FOUND;
END LOOP;
ROLLBACK;
DBMS_OUTPUT.PUT_LINE ('Die zweitniedrigste '
|| 'empno ist ' || v_min);
END;
4-16
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
WHILE Schleife
4
ƒ vor Schleifendurchlauf wird eine Anfangsbedingung überprüft
ƒ Syntax:
WHILE Bedingung LOOP
Anweisung;
{Anweisung;}
END LOOP;
ƒ Beispiel:
DECLARE
v_min number(4);
v_found BOOLEAN := FALSE;
BEGIN
SELECT min(empno) INTO v_min´FROM emp;
WHILE NOT v_found LOOP
v_min := v_min +1;
DELETE FROM emp WHERE empno = v_min;
v_found := SQL%FOUND;
END LOOP;
ROLLBACK;
DBMS_OUTPUT.PUT_LINE (‘Die zweitniedrigste empno ist '|| v_min);
END;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 11
4-17
4
4.2.4
Kontrollstrukturen in PL/SQL
Verschachtelte Schleifen
Schleifen können beliebig ineinander verschachtelt werden. Bei verschachtelten Schleifen wird durch EXIT nur die aktuelle Schleife verlassen und in die nächsthöhere gewechselt. Werden die Schleifen mit
unterschiedlichen Labels benannt, so besteht die Möglichkeit, durch
EXIT labelname [WHEN Bedingung];
auch die entsprechend höhere Schleife zu verlassen.
Beispiel:
DECLARE
v_zaehler PLS_INTEGER :=0;
v_aussen BOOLEAN := FALSE;
v_innen BOOLEAN := FALSE;
BEGIN
<<Erste_Schleife>>
LOOP
v_zaehler := v_zaehler +1;
EXIT WHEN v_zaehler <10;
<<Zweite_Schleife>>
LOOP
....
EXIT Erste_Schleife WHEN v_aussen
=TRUE;
-- beide Schleifen verlassen
EXIT WHEN v_innen
=TRUE;
--nur innere Schleife verlassen
END LOOP Zweite_Schleife;
--hierher wird bei v_innen = TRUE gesprungen
...
END LOOP Erste_Schleife;
--hierher wird bei v_aussen = TRUE gesprungen
...
END;
Die Erwähnung des Schleifennamens bei END LOOP ist optional, erhöht aber die Lesbarkeit.
4-18
1.2.066 / 4053
Kontrollstrukturen in PL/SQL
4
Verschachtelte Schleifen
4
SET SERVEROUPUT ON;
DECLARE
x NUMBER;
BEGIN
...
FOR i in 1..10 LOOP -- Schleife 1
...
FOR j in 1..10 LOOP -- Schleife 2
x := i * j;
DBMS_OUTPUT.PUT_LINE(i ||
‘ mal ‘ || j || ‘ = ‘ || x);
END LOOP;
-- Ende Schleife 2
...
END LOOP;
-- Ende Schleife 1
...
END;
www.unilog.integrata.de
www.unilog-integrata.de
1.2.066 / 4053
4053 / 1.2.036
Folie 12
4-19
4
4-20
Kontrollstrukturen in PL/SQL
1.2.066 / 4053
Herunterladen