Dieses Dokument beschreibt, wie die Ausführung eines Statements von einem Gruppenwechsel abhängig gemacht werden kann, und wie Gruppenwechsel für die Auswertung von Natural-Systemfunktionen benutzt werden können.
Folgende Themen werden behandelt:
Ein Gruppenwechsel (Break) findet statt, wenn der Wert eines Kontrollfeldes sich ändert.
Die Ausführung von Statements kann von einem solchen Gruppenwechsel abhängig gemacht werden.
Ein Gruppenwechsel kann auch zur Auswertung von Natural-Systemfunktionen verwendet werden.
Systemfunktionen werden im Abschnitt Systemvariablen und Systemfunktionen behandelt. Genauere Beschreibungen der verfügbaren Systemfunktionen System finden Sie in der Systemfunktionen-Dokumentation.
Mit dem Statement AT
BREAK
können Sie eine Verarbeitung angeben, die immer dann
ausgeführt werden soll, wenn ein Gruppenwechsel erfolgt, d.h. wenn der Wert
eines Kontrollfeldes, das Sie im AT BREAK
-Statement angeben, sich
ändert. Als Kontrollfeld können Sie ein Datenbankfeld oder eine
Benutzervariable verwenden.
In diesem Abschnitt werden folgende Themen behandelt:
Das Feld, welches als Kontrollfeld in einem
AT BREAK
-Statement
angegeben wird, ist üblicherweise ein Datenbankfeld.
Beispiel:
... AT BREAK OF DEPT statements END-BREAK ...
In diesem Beispiel ist das Datenbankfeld DEPT
das
Kontrollfeld; wechselt der Wert des Feldes, beispielsweise von
SALE01
auf SALE02
, würde dies die Ausführung der im
AT BREAK
-Statement angegebenen Statements auslösen.
Es ist auch möglich, statt eines ganzen Feldes nur einen Teil
eines Feldes als Kontrollfeld zu nehmen. Mit der Notation /n/
können Sie festlegen, dass nur die ersten
/n/
Stellen eines Feldes auf einen
Wertwechsel überprüft werden sollen.
Beispiel:
... AT BREAK OF DEPT /4/ statements END-BREAK ...
In diesem Beispiel würden die angegebenen Statements nur
ausgeführt, wenn sich der Wert der ersten 4 Stellen des Feldes
DEPT
ändern würde, beispielsweise von SALE
auf
TECH
; ein Wechsel von SALE01
auf SALE02
hingegen würde ignoriert und der AT BREAK
-Block nicht ausgeführt
werden.
** Example 'ATBREX01': AT BREAK OF (with database field) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 CITY 2 COUNTRY 2 JOB-TITLE 2 SALARY (1:1) END-DEFINE * READ (5) MYVIEW BY CITY WHERE COUNTRY = 'USA' DISPLAY CITY (AL=9) NAME 'POSITION' JOB-TITLE 'SALARY' SALARY(1) /* AT BREAK OF CITY WRITE / OLD(CITY) (EM=X^X^X^X^X^X^X^X^X^X^X^) 5X 'AVERAGE:' T*SALARY AVER(SALARY(1)) // COUNT(SALARY(1)) 'RECORDS FOUND' / END-BREAK /* AT END OF DATA WRITE 'TOTAL (ALL RECORDS):' T*SALARY(1) TOTAL(SALARY(1)) END-ENDDATA END-READ END
Im obigen Programm wird das erste WRITE
-Statement ausgeführt, wenn
der Wert des Feldes CITY
sich ändert.
Im AT BREAK
-Statement werden die Systemfunktionen
OLD
,
AVER
und
COUNT
ausgewertet (und in dem WRITE
-Statement ausgegeben).
In dem AT END OF
DATA
-Statement wird die Systemfunktion
TOTAL
ausgewertet.
Das Programm ATBREX01
erzeugt folgende Ausgabe:
Page 1 04-12-14 14:07:26 CITY NAME POSITION SALARY --------- -------------------- ------------------------- ---------- AIKEN SENKO PROGRAMMER 31500 A I K E N AVERAGE: 31500 1 RECORDS FOUND ALBUQUERQ HAMMOND SECRETARY 22000 ALBUQUERQ ROLLING MANAGER 34000 ALBUQUERQ FREEMAN MANAGER 34000 ALBUQUERQ LINCOLN ANALYST 41000 A L B U Q U E R Q U E AVERAGE: 32750 4 RECORDS FOUND TOTAL (ALL RECORDS): 162500
Auch eine Benutzervariable kann als Kontrollfeld in
einem AT
BREAK
-Statement verwendet werden.
Im folgenden Programm wird die Benutzervariable
#LOCATION
als Kontrollfeld verwendet.
** Example 'ATBREX02': AT BREAK OF (with user-defined variable and ** in conjunction with BEFORE BREAK PROCESSING) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 CITY 2 COUNTRY 2 JOB-TITLE 2 SALARY (1:1) * 1 #LOCATION (A20) END-DEFINE * READ (5) MYVIEW BY CITY WHERE COUNTRY = 'USA' BEFORE BREAK PROCESSING COMPRESS CITY 'USA' INTO #LOCATION END-BEFORE DISPLAY #LOCATION 'POSITION' JOB-TITLE 'SALARY' SALARY (1) /* AT BREAK OF #LOCATION SKIP 1 END-BREAK END-READ END
Ausgabe des Programms ATBREX02
:
Page 1 04-12-14 14:08:36 #LOCATION POSITION SALARY -------------------- ------------------------- ---------- AIKEN USA PROGRAMMER 31500 ALBUQUERQUE USA SECRETARY 22000 ALBUQUERQUE USA MANAGER 34000 ALBUQUERQUE USA MANAGER 34000 ALBUQUERQUE USA ANALYST 41000
Mit der Notation /n/
können Sie, wie oben erläutert,
den Teil eines Feldes zum Kontrollfeld eines Gruppenwechsels machen. Sie können
auch mehrere AT
BREAK
-Statements miteinander kombinieren, wobei bei einem
Gruppenwechsel ein ganzes Feld und bei einem anderen ein Teil dieses Feldes
Kontrollfeld ist.
In diesem Fall muss der übergeordnete Gruppenwechsel (ganzes Feld)
vor dem untergeordneten (Teil des Feldes) angegeben werden, d.h. im ersten
AT BREAK
-Statement muss das ganze Feld, im zweiten das Teilfeld
als Kontrollfeld angegeben werden.
Das folgende Beispielprogramm zeigt dies anhand des Feldes
DEPT
und den ersten 4 Stellen dieses Feldes (DEPT
/4/
).
** Example 'ATBREX03': AT BREAK OF (two statements in combination) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 JOB-TITLE 2 DEPT 2 SALARY (1:1) 2 CURR-CODE (1:1) END-DEFINE * READ MYVIEW BY DEPT STARTING FROM 'SALE40' ENDING AT 'TECH10' WHERE SALARY(1) GT 47000 AND CURR-CODE(1) = 'USD' /* AT BREAK OF DEPT WRITE '*** LOWEST BREAK LEVEL ***' / END-BREAK AT BREAK OF DEPT /4/ WRITE '*** HIGHEST BREAK LEVEL ***' END-BREAK /* DISPLAY DEPT NAME 'POSITION' JOB-TITLE END-READ END
Ausgabe des Programms ATBREX03
:
Page 1 04-12-14 14:09:20 DEPARTMENT NAME POSITION CODE ---------- -------------------- ------------------------- TECH05 HERZOG MANAGER TECH05 LAWLER MANAGER TECH05 MEYER MANAGER *** LOWEST BREAK LEVEL *** TECH10 DEKKER DBA *** LOWEST BREAK LEVEL *** *** HIGHEST BREAK LEVEL ***
Im folgenden Programm wird jedesmal, wenn sich der Wert des Feldes
DEPT
ändert, eine Leerzeile ausgegeben; und jedesmal, wenn sich
der Wert in den ersten 4 Stellen von DEPT ändert, wird über die Systemfunktion
COUNT
die
Anzahl der verarbeiteten Datensätze ermittelt.
** Example 'ATBREX04': AT BREAK OF (two statements in combination) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 DEPT 2 REDEFINE DEPT 3 #GENDEP (A4) 2 NAME 2 SALARY (1) END-DEFINE * WRITE TITLE '** PERSONS WITH SALARY > 30000, SORTED BY DEPARTMENT **' / LIMIT 9 READ MYVIEW BY DEPT FROM 'A' WHERE SALARY(1) > 30000 DISPLAY 'DEPT' DEPT NAME 'SALARY' SALARY(1) /* AT BREAK OF DEPT SKIP 1 END-BREAK AT BREAK OF DEPT /4/ WRITE COUNT(SALARY(1)) 'RECORDS FOUND IN:' OLD(#GENDEP) / END-BREAK END-READ END
Ausgabe des Programms ATBREX04
:
** PERSONS WITH SALARY > 30000, SORTED BY DEPARTMENT ** DEPT NAME SALARY ------ -------------------- ---------- ADMA01 JENSEN 180000 ADMA01 PETERSEN 105000 ADMA01 MORTENSEN 320000 ADMA01 MADSEN 149000 ADMA01 BUHL 642000 ADMA02 HERMANSEN 391500 ADMA02 PLOUG 162900 ADMA02 HANSEN 234000 8 RECORDS FOUND IN: ADMA COMP01 HEURTEBISE 168800 1 RECORDS FOUND IN: COMP
Automatische Gruppenwechsel-Verarbeitung ist für eine
Verarbeitungsschleife aktiv, die ein AT
BREAK
-Statement enthält. Dies gilt für die folgenden
Statements:
Hierbei wird der Wert des im AT BREAK
-Statement angegebenen
Kontrollfeldes nur bei den Datensätzen überprüft, die die
WITH
- und
WHERE
-Auswahlkriterien
der Verarbeitungsschleife erfüllen.
Natural-Systemfunktionen (AVER
,
MAX
,
MIN
usw.)
werden für jeden Datensatz ausgewertet, nachdem alle in der
Verarbeitungsschleife enthaltenen Statements ausgeführt worden sind.
Datensätze, die aufgrund des WHERE
-Kriteriums
nicht verarbeitet werden, werden bei der Auswertung der Systemfunktionen nicht
berücksichtigt.
Die Abbildung auf der folgenden Seite veranschaulicht den Verarbeitungsablauf eines automatischen Gruppenwechsels.
Das folgende Beispiel zeigt die Verwendung der
Natural-Systemfunktionen
OLD
,
MIN
,
AVER
,
MAX
,
SUM
und
COUNT
in
einem AT
BREAK
-Statement (und der Systemfunktion
TOTAL
in
einem AT END OF
DATA
-Statement).
** Example 'ATBREX05': AT BREAK OF (with system functions) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 CITY 2 SALARY (1:1) 2 CURR-CODE (1:1) END-DEFINE * LIMIT 3 READ MYVIEW BY CITY = 'SALT LAKE CITY' DISPLAY NOTITLE CITY NAME 'SALARY' SALARY(1) 'CURRENCY' CURR-CODE(1) /* AT BREAK OF CITY WRITE / OLD(CITY) (EM=X^X^X^X^X^X^X^X^X^X^X^X^X^X^X) 31T ' - MINIMUM:' MIN(SALARY(1)) CURR-CODE(1) / 31T ' - AVERAGE:' AVER(SALARY(1)) CURR-CODE(1) / 31T ' - MAXIMUM:' MAX(SALARY(1)) CURR-CODE(1) / 31T ' - SUM:' SUM(SALARY(1)) CURR-CODE(1) / 33T COUNT(SALARY(1)) 'RECORDS FOUND' / END-BREAK /* AT END OF DATA WRITE 22T 'TOTAL (ALL RECORDS):' T*SALARY TOTAL(SALARY(1)) CURR-CODE(1) END-ENDDATA END-READ END
Ausgabe des Programms ATBREX05
:
CITY NAME SALARY CURRENCY -------------------- -------------------- ---------- -------- SALT LAKE CITY ANDERSON 50000 USD SALT LAKE CITY SAMUELSON 24000 USD S A L T L A K E C I T Y - MINIMUM: 24000 USD - AVERAGE: 37000 USD - MAXIMUM: 50000 USD - SUM: 74000 USD 2 RECORDS FOUND SAN DIEGO GEE 60000 USD S A N D I E G O - MINIMUM: 60000 USD - AVERAGE: 60000 USD - MAXIMUM: 60000 USD - SUM: 60000 USD 1 RECORDS FOUND TOTAL (ALL RECORDS): 134000 USD
Siehe folgendes Beispielprogramm:
Mit dem Statement BEFORE
BREAK PROCESSING
können Sie Statements angeben, die
unmittelbar vor einem Gruppenwechsel ausgeführt werden sollen, d.h. bevor der
Wert des Kontrollfeldes geprüft wird, bevor die Statements im
AT BREAK
-Block
ausgeführt werden und bevor Natural-Systemfunktionen ausgewertet
werden.
** Example 'BEFORX01': BEFORE BREAK PROCESSING ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 FIRST-NAME 2 SALARY (1:1) 2 BONUS (1:1,1:1) * 1 #INCOME (P11) END-DEFINE * LIMIT 5 READ MYVIEW BY NAME FROM 'B' BEFORE BREAK PROCESSING COMPUTE #INCOME = SALARY(1) + BONUS(1,1) END-BEFORE /* DISPLAY NOTITLE NAME FIRST-NAME (AL=10) 'ANNUAL/INCOME' #INCOME 'SALARY' SALARY(1) (LC==) / '+ BONUS' BONUS(1,1) (IC=+) AT BREAK OF #INCOME WRITE T*#INCOME '-'(24) END-BREAK END-READ END
Ausgabe des Programms BEFORX01
:
NAME FIRST-NAME ANNUAL SALARY INCOME + BONUS -------------------- ---------- ------------ ----------- BACHMANN HANS 56800 = 52800 +4000 ------------------------ BAECKER JOHANNES 81000 = 74400 +6600 ------------------------ BAECKER KARL 52650 = 48600 +4050 ------------------------ BAGAZJA MARJAN 152700 = 129700 +23000 ------------------------ BAILLET PATRICK 198500 = 188000 +10500 ------------------------
Bei automatischer Gruppenwechsel-Verarbeitung werden die im AT
BREAK-Block angegebenen Statements jedesmal ausgeführt, wenn sich der Wert des
angegebenen Kontrollfeldes ändert, und zwar unabhängig von der Position des
AT BREAK
-Statements
in der Verarbeitungsschleife.
Mit einem PERFORM BREAK
PROCESSING
-Statement können Sie selbst festlegen, wo in einer
Verarbeitungsschleife eine Gruppenwechsel-Verarbeitung ausgeführt werden soll.
Das PERFORM BREAK PROCESSING
-Statement wird dann ausgeführt, wenn
es im Verarbeitungsablauf des Programms angetroffen wird.
Unmittelbar nach dem PERFORM BREAK PROCESSING
-Statement
geben Sie einen oder mehrere AT BREAK
-Statement-Blöcke an:
... PERFORM BREAK PROCESSING AT BREAK OF field1 statements END-BREAK AT BREAK OF field2 statements END-BREAK ...
Wenn ein PERFORM BREAK PROCESSING
-Statement ausgeführt
wird, prüft Natural, ob ein Gruppenwechsel stattgefunden hat, d.h. ob der Wert
des angegebenen Kontrollfeldes sich geändert hat; ist dies der Fall, dann
werden die angegebenen Statements ausgeführt.
Bei PERFORM BREAK PROCESSING
werden Systemfunktionen
ausgewertet, bevor Natural prüft, ob ein Gruppenwechsel stattgefunden
hat.
Die folgende Abbildung zeigt den logischen Ablauf einer programmabhängigen Gruppenwechsel-Verarbeitung:
** Example 'PERFBX01': PERFORM BREAK PROCESSING (with BREAK option ** in IF statement) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 DEPT 2 SALARY (1:1) * 1 #CNTL (N2) END-DEFINE * LIMIT 7 READ MYVIEW BY DEPT AT BREAK OF DEPT /* <- automatic break processing SKIP 1 WRITE 'SUMMARY FOR ALL SALARIES ' 'SUM:' SUM(SALARY(1)) 'TOTAL:' TOTAL(SALARY(1)) ADD 1 TO #CNTL END-BREAK /* IF SALARY (1) GREATER THAN 100000 OR BREAK #CNTL PERFORM BREAK PROCESSING /* <- user-initiated break processing AT BREAK OF #CNTL WRITE 'SUMMARY FOR SALARY GREATER 100000' 'SUM:' SUM(SALARY(1)) 'TOTAL:' TOTAL(SALARY(1)) END-BREAK END-IF /* IF SALARY (1) GREATER THAN 150000 OR BREAK #CNTL PERFORM BREAK PROCESSING /* <- user-initiated break processing AT BREAK OF #CNTL WRITE 'SUMMARY FOR SALARY GREATER 150000' 'SUM:' SUM(SALARY(1)) 'TOTAL:' TOTAL(SALARY(1)) END-BREAK END-IF DISPLAY NAME DEPT SALARY(1) END-READ END
Ausgabe des Programms PERFBX01
:
Page 1 04-12-14 14:13:35 NAME DEPARTMENT ANNUAL CODE SALARY -------------------- ---------- ---------- JENSEN ADMA01 180000 PETERSEN ADMA01 105000 MORTENSEN ADMA01 320000 MADSEN ADMA01 149000 BUHL ADMA01 642000 SUMMARY FOR ALL SALARIES SUM: 1396000 TOTAL: 1396000 SUMMARY FOR SALARY GREATER 100000 SUM: 1396000 TOTAL: 1396000 SUMMARY FOR SALARY GREATER 150000 SUM: 1142000 TOTAL: 1142000 HERMANSEN ADMA02 391500 PLOUG ADMA02 162900 SUMMARY FOR ALL SALARIES SUM: 554400 TOTAL: 1950400 SUMMARY FOR SALARY GREATER 100000 SUM: 554400 TOTAL: 1950400 SUMMARY FOR SALARY GREATER 150000 SUM: 554400 TOTAL: 1696400