Eine Verarbeitungsschleife ist eine Gruppe von Statements, deren Ausführung so oft wiederholt wird, bis eine bestimmte Bedingung erfüllt ist, oder solange eine bestimmte Bedingung gegeben ist.
Dieser Abschnitt behandelt folgende Themen:
Verarbeitungsschleifen lassen sich in Datenbankschleifen und Nicht-Datenbankschleifen unterteilen:
Datenbankschleifen
werden von Natural automatisch erzeugt, um die Daten, die mit einem READ-, FIND- oder HISTOGRAM-Statement von einer Datenbank gelesen werden,
zu verarbeiten. Diese Statements sind im Kapitel Datenbankzugriffe beschrieben.
Nicht-Datenbankschleifen
(d.h. Schleifen ohne Datenbankzugriff) werden mit folgenden Statements erzeugt:
REPEAT, FOR, CALL FILE, CALL
LOOP, SORT und READ WORK
FILE.
Es können mehrere Verarbeitungsschleifen gleichzeitig aktiv sein. In einer gerade aktiven, d.h. noch nicht abgeschlossenen Schleife können weitere Schleifen eingebettet werden.
Jede Verarbeitungsschleife muss durch ein entsprechendes END-...-Statement
beendet werden (z.B. END-REPEAT, END-FOR usw.).
Das SORT-Statement, mit dem das
Sortierprogramm des Betriebssystems aufgerufen wird, beendet alle aktiven Schleifen und
löst eine neue Schleife aus.
Die folgenden Themen werden behandelt:
Bei den Statements READ,
FIND oder HISTOGRAM haben Sie drei
Möglichkeiten, die Anzahl, wie oft eine Verarbeitungsschleife durchlaufen werden soll,
zu begrenzen:
mit dem Session-Parameter LT
mit einem LIMIT-Statement
oder mit einer Limit-Notation im
READ-/FIND-/HISTOGRAM-Statement selbst.
Mit dem Systemkommando GLOBALS können Sie den Session-Parameter
LT angeben, der die
Anzahl der Datensätze, die in einer Datenbank-Verarbeitungsschleife gelesen werden
sollen, begrenzt.
GLOBALS LT=100
Dieses Limit gilt für alle READ-, FIND- und HISTOGRAM-Schleifen in der gesamten Session.
In einem Programm können Sie die Anzahl der Datensätze, die in einer
Datenbank-Verarbeitungsschleife gelesen werden sollen, mit einem LIMIT-Statement begrenzen.
LIMIT 100
Das LIMIT-Statement gilt für alle nachfolgenden READ-, FIND- oder HISTOGRAM-Schleifen im Programm, es sein denn, es wird
durch ein anderes LIMIT-Statement oder eine Limit-Notation außer Kraft
gesetzt.
In einem READ-, FIND- oder HISTOGRAM-Statement selbst können Sie
die Anzahl der Datensätze, die gelesen werden sollen, in Klammern unmittelbar hinter dem
Statement-Namen angeben.
READ (10) VIEWXYZ BY NAME
Diese Limit-Notation hat Vorrang vor allen anderen Limits, gilt aber nur für das betreffende Statement.
Wenn das mit dem LT-Parameter angegebene Limit kleiner ist als ein mit
einem LIMIT-Statement oder einer
Limit-Notation angegebenes, dann hat das LT-Limit Vorrang vor
diesen anderen Limits.
Anfang und Ende von Verarbeitungsschleifen, die keinen Datenbankzugriff beinhalten,
basieren auf einer logischen oder sonstwie die Schleife begrenzenden Bedingung. Sie werden
mit einem der folgenden Statements erzeugt: REPEAT, FOR, CALL
FILE, CALL
LOOP, SORT und
READ WORK FILE.
Stellvertretend für Nicht-Datenbankschleifen-Statements wird hier das Statement
REPEAT behandelt.
Mit dem REPEAT-Statement geben Sie ein oder mehrere Statements an, die
wiederholt ausgeführt werden sollen. Außerdem können Sie eine logische Bedingung angeben,
so dass die Statements nur ausgeführt werden, solange oder bis diese Bedingung erfüllt
ist. Die Bedingung geben Sie in einer UNTIL-Klausel oder in einer WHILE-Klausel an:
Bei einer UNTIL-Klausel wird die Schleife so oft ausgeführt, bis
(UNTIL) die logische Bedingung erfüllt ist, d.h. die Schleife wird
beendet, sobald der in der Bedingung angegebene Zustand erreicht ist.
Bei einer WHILE-Klausel wird die REPEAT-Schleife
ausgeführt, während (WHILE) der in der Bedingung angegebene Zustand
besteht, d.h. die Schleife wird beendet, sobald die Bedingung nicht mehr erfüllt
wird.
Wenn Sie keine logische Bedingung angeben, muss die REPEAT-Schleife
mit einem der folgenden Statements verlassen werden:
ESCAPE (siehe nächsten
Abschnitt) beendet die Verarbeitung der Schleife und setzt die
Verarbeitung außerhalb der Schleife fort.
STOP bricht die Ausführung der
gesamten Natural-Anwendung ab.
TERMINATE bricht die
Ausführung der Natural-Anwendung ab und beendet die Natural-Session.
** Example 'REPEAX01': REPEAT
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 SALARY (1:1)
*
1 #PAY1 (N8)
END-DEFINE
*
READ (5) MYVIEW BY NAME WHERE SALARY (1) = 30000 THRU 39999
MOVE SALARY (1) TO #PAY1
/*
REPEAT WHILE #PAY1 LT 40000
MULTIPLY #PAY1 BY 1.1
DISPLAY NAME (IS=ON) SALARY (1)(IS=ON) #PAY1
END-REPEAT
/*
SKIP 1
END-READ
END
Ausgabe des Programms REPEAX01:
Page 1 04-11-11 14:15:54
NAME ANNUAL #PAY1
SALARY
-------------------- ---------- ---------
ADKINSON 34500 37950
41745
33500 36850
40535
36000 39600
43560
AFANASSIEV 37000 40700
ALEXANDER 34500 37950
41745
Mit dem ESCAPE-Statement können
Sie die Ausführung einer Verarbeitungsschleife abbrechen, und zwar aufgrund einer
logischen Bedingung.
Das ESCAPE-Statement kann Teil eines IF-Statements sein oder an eines der Statements AT END OF DATA, AT END OF PAGE oder AT BREAK geknüpft sein; es kann aber
auch als eigenständiges Statement in Ausführung der einer Verarbeitungsschleife
zugrundeliegenden logischen Bedingungen stehen.
Mit dem ESCAPE-Statement haben Sie die Optionen TOP und
BOTTOM, mit denen Sie festlegen, wo die Verarbeitung fortgesetzt werden
soll, nachdem die Schleife mit ESCAPE verlassen wurde:
Bei ESCAPE TOP
wird die Verarbeitung am Anfang der Schleife, d.h. mit dem nächsten
Schleifendurchlauf, fortgesetzt.
Bei ESCAPE
BOTTOM wird die Verarbeitung mit dem ersten Statement, das nach
der Schleife kommt, fortgesetzt.
Sie können innerhalb einer Verarbeitungsschleife auch mehrere
ESCAPE-Statements angeben.
Weitere Informationen und Beispiele zum ESCAPE-Statement finden Sie in der
Statements-Dokumentation.
Mit Natural haben Sie die Möglichkeit, Schleifen innerhalb von Schleifen auszulösen und so eine ganze "Hierarchie" ineinander verschachtelter Schleifenkonstruktionen aufzubauen. Sind mehrere Datenbankzugriffsschleifen ineinander verschachtelt, so durchläuft jeder gelesene Datensatz, der die Auswahlkriterien erfüllt, nacheinander die einzelnen Schleifen, bevor der nächste Datensatz verarbeitet wird.
Mehrere Datenbankzugriffs- und Nicht-Datenbankzugriffsschleifen können ineinander verschachtelt werden. Verarbeitungsschleifen können auch Teil einer bedingten Verarbeitung sein.
Das folgende Programm zeigt eine Hierarchie zweier Verarbeitungsschleifen, wobei sich
eine FIND-Schleife innerhalb einer
anderen FIND-Schleife befindet.
** Example 'FINDX06': FIND (two FIND statements nested)
************************************************************************
DEFINE DATA LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
2 CITY
2 NAME
2 PERSONNEL-ID
1 VEH-VIEW VIEW OF VEHICLES
2 MAKE
2 PERSONNEL-ID
END-DEFINE
*
FND1. FIND EMPLOY-VIEW WITH CITY = 'NEW YORK' OR = 'BEVERLEY HILLS'
FIND (1) VEH-VIEW WITH PERSONNEL-ID = PERSONNEL-ID (FND1.)
DISPLAY NOTITLE NAME CITY MAKE
END-FIND
END-FIND
END
Das obige Programm liest Daten von mehreren Dateien. Die äußere
FIND-Schleife wählt von der EMPLOYEES-Datei alle Personen aus,
die in New York oder Beverley Hills wohnen. Für jeden in der äußeren Schleife ausgewählten
Datensatz wird die innere FIND-Schleife durchlaufen, in der die Fahrzeugdaten
der betreffenden Personen von der VEHICLES-Datei gelesen werden.
Ausgabe des Programms FINDX06:
NAME CITY MAKE
-------------------- -------------------- --------------------
RUBIN NEW YORK FORD
OLLE BEVERLEY HILLS GENERAL MOTORS
WALLACE NEW YORK MAZDA
JONES BEVERLEY HILLS FORD
SPEISER BEVERLEY HILLS GENERAL MOTORS
Statement-Referenzierung dient dazu
in einem Programm auf ein vorhergehendes Statement zu verweisen (d.h. dieses Statement zu "referenzieren"), um eine Verarbeitung für einen bestimmten Bereich von Daten auszuführen,
Naturals Standard-Referenzierung (die bei jedem betroffenen Statement in der Dokumentation beschrieben ist) aufzuheben
oder zu Programmdokumentationszwecken.
Sie können jedes Natural-Statement referenzieren, das eine Verarbeitungsschleife initiiert und/oder auf Datenelemente in einer Datenbank zugreift:
Enthält ein Programm mehrere Verarbeitungsschleifen, so kann man ein bestimmtes Datenbankfeld eindeutig identifizieren, indem man das Statement referenziert, welches zuerst auf das entsprechende Feld in der Datenbank zugriff.
Welche Felder bei welchem Statement referenziert werden dürfen, ersehen Sie in der
Statements-Dokumentation in den Operandentabellen der einzelnen Statements aus der
Spalte Referenzierung
erlaubt. Siehe auch Benutzervariablen, Datenbankfelder mit der
(r)-Notation referenzieren.
Außerdem kann eine Referenzierungsnotation in einigen Statements angegeben werden, z.B. bei:
Normalerweise bezieht sich bei einem AT START OF DATA-, AT END OF
DATA- oder AT BREAK-Statement die schleifenbeendende Gruppenwechsel-Bedingung auf die jeweils äußerste
aktive READ-, FIND-, HISTOGRAM-, SORT-
oder READ WORK FILE-Schleife. Mit einer Referenzierungsnotation können Sie
die Bedingung auf eine beliebige andere aktive Schleife beziehen.
Wenn Sie bei einem ESCAPE
BOTTOM-Statement ein Statement referenzieren, wird die Verarbeitung
unmittelbar nach der durch das referenzierte Statement identifizierten Schleife
fortgesetzt.
Zur Statement-Referenzierung können Sie entweder ein sogenanntes Statement-Label oder die Quellcode-Zeilennummer verwenden.
Statement-Label
Ein Statement-Label ist eine Zeichenkette, deren letztes Zeichen ein Punkt (.) sein
muss. Der Punkt identifiziert die Zeichenkette als Label.
Ein Statement, das referenziert werden soll, wird mit einem Label markiert, indem das Label an den Anfang der Zeile gestellt wird, in der das Statement steht, zum Beispiel:
0030 ... 0040 READ1. READ VIEWXYZ BY NAME 0050 ...
In dem Statement, das das markierte Statement referenziert, wird das Label in Klammern an der in der Statement-Syntax dafür vorgesehenen Stelle (siehe Syntaxdiagramme in der Statements-Dokumentation) eingefügt, zum Beispiel:
AT BREAK (READ1.) OF NAME
Quellcode-Zeilennummern
Wenn Sie Quellcode-Zeilennummern zur Referenzierung verwenden, müssen Sie diese immer
vierstellig (vorangestellte Nullen dürfen nicht weggelassen werden) und in Klammern
angeben, zum Beispiel:
AT BREAK (0040) OF NAME
Bezieht sich in einem Statement ein bestimmtes Feld auf ein vorhergegangenes Statement, so wird das Label bzw. die Zeilennummer in Klammern hinter dem jeweiligen Feldnamen angegeben, zum Beispiel:
DISPLAY NAME (READ1.) JOB-TITLE (READ1.) MAKE MODEL
Quellcode-Zeilennummern und Statement-Labels können wahlweise verwendet werden.
Siehe auch Benutzervariablen, Datenbankfelder mit der (r)- Notation referenzieren.
Das folgende Programm verwendet Quellcode-Zeilennummern (vierstellige Ziffern in Klammern) zur Referenzierung.
In diesem Beispiel beziehen sich die Zeilennummern auf Statements, die aufgrund der Programmstruktur ohnehin, auch ohne explizite Referenzierung, referenziert worden wären.
0010 ** Example 'LABELX01': Labels for READ and FIND loops (line numbers) 0020 ************************************************************************ 0030 DEFINE DATA LOCAL 0040 1 MYVIEW1 VIEW OF EMPLOYEES 0050 2 NAME 0060 2 FIRST-NAME 0070 2 PERSONNEL-ID 0080 1 MYVIEW2 VIEW OF VEHICLES 0090 2 PERSONNEL-ID 0100 2 MAKE 0110 END-DEFINE 0120 * 0130 LIMIT 15 0140 READ MYVIEW1 BY NAME STARTING FROM 'JONES' 0150 FIND MYVIEW2 WITH PERSONNEL-ID = PERSONNEL-ID (0140) 0160 IF NO RECORDS FOUND 0170 MOVE '***NO CAR***' TO MAKE 0180 END-NOREC 0190 DISPLAY NOTITLE NAME (0140) (IS=ON) 0200 FIRST-NAME (0140) (IS=ON) 0210 MAKE (0150) 0220 END-FIND /* (0150) 0230 END-READ /* (0140) 0240 END
Das folgende Beispiel zeigt die Verwendung von Statement-Labels.
Es ist mit dem vorigen Beispielprogramm identisch bis auf die Tatsache, dass zur Referenzierung der Statements Labels anstelle von Zeilennummern verwendet werden.
** Example 'LABELX02': Labels for READ and FIND loops (user labels)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW1 VIEW OF EMPLOYEES
2 NAME
2 FIRST-NAME
2 PERSONNEL-ID
1 MYVIEW2 VIEW OF VEHICLES
2 PERSONNEL-ID
2 MAKE
END-DEFINE
*
LIMIT 15
RD. READ MYVIEW1 BY NAME STARTING FROM 'JONES'
FD. FIND MYVIEW2 WITH PERSONNEL-ID = PERSONNEL-ID (RD.)
IF NO RECORDS FOUND
MOVE '***NO CAR***' TO MAKE
END-NOREC
DISPLAY NOTITLE NAME (RD.) (IS=ON)
FIRST-NAME (RD.) (IS=ON)
MAKE (FD.)
END-FIND /* (FD.)
END-READ /* (RD.)
END
Beide Programme erzeugen folgende Ausgabe:
NAME FIRST-NAME MAKE
-------------------- -------------------- --------------------
JONES VIRGINIA CHRYSLER
MARSHA CHRYSLER
CHRYSLER
ROBERT GENERAL MOTORS
LILLY FORD
MG
EDWARD GENERAL MOTORS
LAUREL GENERAL MOTORS
KEVIN DATSUN
GREGORY FORD
JOPER MANFRED ***NO CAR***
JOUSSELIN DANIEL RENAULT
JUBE GABRIEL ***NO CAR***
JUNG ERNST ***NO CAR***
JUNKIN JEREMY ***NO CAR***
KAISER REINER ***NO CAR***
KANT HEIKE ***NO CAR***