| Steuerung des Programmfluß |
|
|
| Donnerstag, 16. Oktober 2008 um 14:43 | ||||
|
Wie in anderen Programmiersprachen auch gibt es im wesentlichen zwei Konstrukte für die Steuerung des Programmfluss.
IF-THENDas Format des IF THEN Statements ist wie folgt: IF <condition> THEN Die Bedingung wird ausgewertet. Wenn die Bedingung wahr ist, werden die ausführbaren Anweisungen ausgeführt. Wenn die Bedingung falsch oder NULL ist, werden die ausführbaren Anweisungen übersprungen. IF-ELSIF-ELSEDas ELSIF ist kein typografischer Fehler. Das Format des IF-ELSIF Statement ist wie folgt: IF <condition1> THEN Das IF-ELSIF-ELSE Statement kann begriffen werden als viele IF-THEN Statements, von denen nur eine wahr sein kann. Tatsächlich werden die folgenden Bedingungen nicht mehr ausgewertet, sobald die erste wahr ist. Ist keine der Bedingungen wahr, wird der ELSE-Teil ausgeführt. Verschachtelte IF StatementsEs ist möglich, mehrere IF Statements zu verschachteln. Als Faustregel gilt, wenn mehr als drei Verschachtelungstiefen vorliegen, sollte man seinen Code kritisch betrachten. Grundsätzlich ist die Verschachtelungstiefe unendlich, praktisch hängt sie von den Serverressourcen ab. Das GOTO StatementEigentlich wollen wir gar nicht wissen, dass es das GOTO Statement gibt, denn durch seine Verwendung lässt sich herrlich verwirrender Programmcode erzeugen. Nun, obwohl sich beweisen lässt, dass man in der Programmierung ohne die verpönte Sprunganweisung auskommt, sei sie hier dennoch erwähnt. Als Sprungziel nutzt man sogenannte Labels. Labels spielen neben einem Sprungziel auch eine Rolle für die Sichtbarkeit von Variablen in verschachtelten Blöcken. Beispiel: DECLARE Neben konditionalen Konstrukten gibt es noch Schleifenkonstrukte SchleifenkonstrukteDie Fähigkeit, Schleifen zu formulieren ist einer der Hauptunterschiede zwischen SQL und PL/SQL, so dass wir diesen Unterschied sehr genau betrachten wollen. Schleifenkonstrukte sind recht einfach und leicht zu verstehen.
Warum gibt es drei verschiedene Konstrukte. Für Flexibilität. Nun, ich nutze trotzdem meist nur eine Form. In der Literatur werden Sie noch von einer weiteren Schleifenform lesen, der CURSOR-FOR-LOOP. Diese Schleife ist ein sehr mächtiges Konzept, auf das wir aber erst eingehen im Bereich der Datenbank-Interaktion. Die einfache SchleifeDie einfache Schleife wird auch als Endlos-Schleife bezeichnet. Warum das der Fall ist, sehen wir gleich. Die Syntax für die einfache Schleife ist wie folgt: LOOP Versuchen wir ein Beispiel: Geben Sie in SQL*Plus folgendes ein: set serveroutput on Wenn Sie diesen Code ausführen, sehen Sie die Zahlen 1 bis 10 auf dem Bildschirm. Der Schleifencode wird solange ausgeführt bis die EXIT WHEN Bedingung wahr wird. Der Aufruf von DBMS_OUTPUT erzeugt Bildschirmausgaben, darum kümmern wir uns später. Diese Schleifenform heißt auch rumpfgesteuerte Schleife, denn sie wird mindestens einmal ausgeführt. Ob weitere Durchläufe erfolgen, entscheidet sich innerhalb der Schleife (also im Rumpf) mit Hilfe der EXIT WHEN Bedingung. Fehlt diese oder wird niemals wahr, haben Sie eine Endlosschleife produziert, die niemals terminiert. Ein klassischer FehlerDECLARE Nun, sieht ja fast aus wie das vorige Beispiel, ist aber eine Endlosschleife. Wo liegt das Problem? Wir haben versäumt, die Variable i mit einem Wert zu initialisieren. Der Variableninhalt von i ist im ausführbaren Teil also NULL, unbekannt. Selbst wenn wir i um eins erhöhen: unbekannt erhöht um eins ist? Unbekannt! Die EXIT WHEN Bedingung wird daher niemals wahr, also terminiert die Schleife nicht. Die numerische SchleifeNumerische Schleifen führen den Schleifenrumpf eine feste Anzahl Male aus, die Häufigkeit wird mit dem Schleifenindex festgelegt. Die Syntax für numerische Schleifen ist: FOR loop_index IN lower_range .. upper_range LOOP Beispiel set serveroutput on Der Code wird zehnmal ausgeführt. Es demonstriert also eine andere Form der einfachen Schleife. Die numerische Schleife wird genutzt, wenn Sie die Anzahl Schleifendurchläufe kennen und Sie die Schleife nicht bereits vorher abbrechen wollen. Erwähnt sei folgendes: Die Syntax min .. max ist sehr selten, es handelt sich nicht um einen Schreibfehler! Der Schleifenindex i muß nicht deklariert werden! Innerhalb des Schleifenrumpfs darf keine Wertzuweisung an i erfolgen. Schleifen zählen nur ganzzahlig und stets mit dem Inkrement (oder Dekrement) 1. Es ist also auch möglich, rückwärts zu zählen: set serveroutput on Diese Schleife zählt von zehn bis eins rückwärts. Wichtig ist, dass Sie nicht die Ober- und Untergrenze des Intervalls einfach umdrehen, sondern das Schlüsselwort REVERSE nutzen. Im Gegenteil, wenn die Untergrenze (links) größer als die Obergrenze (rechts) ist, wird die Schleife gar nicht ausgeführt. Es handelt sich hier also nicht um eine rumpfgesteuerte, sondern eine sogenannte kopfgesteuerte Schleife: Ob ein Schleifendurchlauf erfolgt oder nicht, wird vor Schleifeneintritt geprüft. Der Grund für die Nutzung von Schleifen liegt nun weniger in der Anzeige von Zahlen, sondern vielmehr, um bspw. Datensätze zu bearbeiten, die aus der Datenbank “gefetcht” werden. Hierfür können wir entweder die einfache Schleife oder die sogenannte Cursor-Schleife nutzen (den Cursor werden wir später behandeln). Hier ein Beispiel mit der einfachen Schleife DECLARE Hier geschehen mehrere spannende Sachen: Im DECLARE Teil wird eine zusammengesetzte Variable deklariert, ein sogenannter Record, dessen Aufbau sich aus dem Rückgabewert des Cursors ableitet. Für den Datentypen verwendet man hierbei die verankerte Methode und bezieht sich mit %ROWTYPE auf den Aufbau z.B. einer Tabelle oder aber eines Cursors. In der LOOP Schleife wird nun der gesamte Datensatz aus dem Cursor nicht in einzelne Variablen gestellt, sondern in den Record, der ja den korrekten Aufbau hat. Dazu später mehr. Nach dem FETCH überprüfen wir, ob noch ein Datensatz im Cursor zur Verfügung steht. Wenn nicht, wurden also alle verarbeitet, wir verlassen die Schleife und schließen den Cursor. Die FOR-CURSOR-LOOPHier ein anderes Beispiel für die Verarbeitung von Datensätzen. Wir führen jetzt die sogenannte FOR-CURSOR-LOOP ein: DECLARE Nun, das ist die Schleifenvariante mit dem wenigsten Tippaufwand. Was passiert. Im FOR-LOOP Konstrukt erfolgt bereits das FETCH aus dem Cursor in den Record. Wir brauchen kein Ende-Kriterium, die Schleife terminiert, wenn keine Datensätze mehr im Cursor zur Verfügung stehen. Besonderheit: Der Cursor muß weder geöffnet noch geschlossen werden, das geschieht automatisch. Weitere Besonderheit: Der Record c_students_rec muß nicht deklariert werden. Auch dies geschieht automatisch. Warum hat die erste Variante dennoch ihre Existenzberechtigung, wenn es doch auch einfacher geht? Die einfache Schleife ist dann zu bevorzugen, wenn der Schleifenabbruch bereits erfolgen kann, ohne alle Datensätze verarbeitet haben zu müssen. Das hier vorgestellte Konstrukt verarbeitet erst alle Datensätze, dann terminiert die FOR-CURSOR-LOOP. Die WHILE-SchleifeDie WHILE-Schleife wird solange ausgeführt wie eine Testbedingung wahr ist. set serveroutput on Die WHILE Schleife wird genutzt, wenn nicht bekannt ist, wie häufig die Schleife ausgeführt werden muß und die Durchführung der Schleife unter Umständen gar nicht nötig ist. Denn ist die WHILE-Bedingung beim Schleifeneintritt bereits unwahr, wird die Schleife gar nicht ausgeführt.
|
||||
| Aktualisiert ( Dienstag, 01. September 2009 um 06:33 ) | ||||


Kommentare
Deine Frage ist berechtigt, Du hast einen Fehler im Beispielcode entdeckt.
Ich korrigiere sofort… Zitieren
"BEGIN
DECLARE CURSOR c_students IS
SELECT * FROM students;…"
Warum haben wir hier im Declare-Teil auch ein Begin??
Danke. Zitieren
Alle Kommentare dieses Beitrages als RSS-Feed.