COBOL auf BS2000: Fundamente der Geschäftslogik auf dem Mainframe

Die Entwicklung von robusten und effizienten Anwendungen auf dem Mainframe erfordert ein tiefes Verständnis der COBOL-Sprache und ihrer Interaktion mit dem Betriebssystem. Als Herzstück vieler Geschäftsprozesse auf Systemen wie BS2000 sind COBOL-Programme nicht nur Legacy, sondern lebendige Komponenten, die täglich performen müssen. Heute tauchen wir ein in einige fundamentale Aspekte, die jeder Mainframe-Entwickler meistern sollte: Dateiverarbeitung, logische Entscheidungsfindung und effiziente Datenstrukturen.

1. Dateiverarbeitung 101: Sequentielle Dateien in COBOL lesen und schreiben
Sequentielle Dateien sind das A und O der Datenhaltung auf dem Mainframe, insbesondere in Stapelverarbeitungen. Sie sind schlicht und effizient für das Speichern und Abrufen von Datensätzen in einer bestimmten Reihenfolge. Auf BS2000-Systemen werden sie vom Data Management System (DMS) verwaltet, und COBOL bietet die nötigen Sprachkonstrukte, um sie zu handhaben.
Kernkonzepte:
SELECTundASSIGN: Verbindet einen logischen Dateinamen im COBOL-Programm mit einem externen Dateinamen oder einer Link-Definition, die über das JCL (oder BS2000 Command Procedures wie/ADD-FILE-LINK) bereitgestellt wird.FD(File Description): Beschreibt die Struktur der Datei, inklusive Satzlänge und Record-Format.OPEN,READ,WRITE,CLOSE: Die grundlegenden Operationen.READholt den nächsten Datensatz,WRITEfügt einen neuen hinzu.AT ENDist hierbei Ihr bester Freund, um das Dateiende zu erkennen.
Beispiel: Eine einfache Dateikopie
Dieses COBOL-Programm liest Datensätze von einer sequentiellen Eingabedatei und schreibt sie unverändert in eine sequentielle Ausgabedatei. Beachten Sie, dass die Daten auf dem Mainframe üblicherweise im EBCDIC-Format vorliegen.
IDENTIFICATION DIVISION.
PROGRAM-ID. SEQDEMO.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO INFILE
ORGANIZATION IS SEQUENTIAL.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE
ORGANIZATION IS SEQUENTIAL.
*
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE
RECORD CONTAINS 80 CHARACTERS
LABEL RECORDS ARE STANDARD
DATA RECORD IS IN-RECORD.
01 IN-RECORD PIC X(80).
*
FD OUTPUT-FILE
RECORD CONTAINS 80 CHARACTERS
LABEL RECORDS ARE STANDARD
DATA RECORD IS OUT-RECORD.
01 OUT-RECORD PIC X(80).
*
WORKING-STORAGE SECTION.
01 WS-EOF-FLAG PIC X VALUE 'N'.
88 END-OF-FILE VALUE 'Y'.
*
PROCEDURE DIVISION.
MAIN-PARA.
OPEN INPUT INPUT-FILE
OUTPUT OUTPUT-FILE.
*
PERFORM UNTIL END-OF-FILE
READ INPUT-FILE
AT END SET END-OF-FILE TO TRUE
NOT AT END
WRITE OUT-RECORD FROM IN-RECORD
END-PERFORM.
*
CLOSE INPUT-FILE
OUTPUT-FILE.
*
STOP RUN.
In einer BS2000-Umgebung würde man die Dateiverknüpfungen (File-Links) typischerweise so definieren:
/ADD-FILE-LINK INFILE, <name-der-eingabedatei>
/ADD-FILE-LINK OUTFILE, <name-der-ausgabedatei>
/START-COBOL-PROGRAM SEQDEMO

2. Conditionals: Logik mit IF-ELSE und EVALUATE (Case-Struktur) implementieren
Die Fähigkeit, Entscheidungen basierend auf Daten zu treffen, ist das Herzstück jeder sinnvollen Geschäftslogik. COBOL bietet hierfür leistungsstarke und klar strukturierte Conditional-Anweisungen.
IF-ELSE: Die grundlegende Verzweigung
IF-ELSE ermöglicht es Ihnen, einen Codeblock auszuführen, wenn eine Bedingung wahr ist, und optional einen anderen, wenn sie falsch ist.
WORKING-STORAGE SECTION.
01 WS-KUNDENSTATUS PIC X(01).
88 STATUS-VIP VALUE 'V'.
88 STATUS-STANDARD VALUE 'S'.
88 STATUS-NEU VALUE 'N'.
01 WS-WARENWERT PIC 9(05)V99.
PROCEDURE DIVISION.
LOGIK-PARA.
MOVE 'V' TO WS-KUNDENSTATUS.
MOVE 125.75 TO WS-WARENWERT.
IF STATUS-VIP
DISPLAY 'VIP-Kunde: Rabatt anwenden.'
PERFORM BERECHNE-VIP-RABATT
ELSE IF STATUS-STANDARD AND WS-WARENWERT > 100.00
DISPLAY 'Standard-Kunde mit hohem Einkauf: Versandkostenfrei.'
PERFORM BERECHNE-VERSANDKOSTENFREI
ELSE
DISPLAY 'Standard-Kunde oder Neukunde.'
PERFORM BERECHNE-NORMALEN-PREIS
END-IF.
STOP RUN.
BERECHNE-VIP-RABATT.
DISPLAY 'VIP-Rabattlogik hier...'.
BERECHNE-VERSANDKOSTENFREI.
DISPLAY 'Versandkostenfrei-Logik hier...'.
BERECHNE-NORMALEN-PREIS.
DISPLAY 'Normalpreis-Logik hier...'.
Die Verwendung von Level-88-Bedingungen (STATUS-VIP, STATUS-STANDARD) verbessert die Lesbarkeit erheblich.
EVALUATE: Die elegante Case-Struktur
Für komplexere Entscheidungsbäume, bei denen ein einzelner Wert mit mehreren Optionen verglichen werden muss, ist EVALUATE die sauberere und wartungsfreundlichere Wahl gegenüber verschachtelten IF-Anweisungen.
WORKING-STORAGE SECTION.
01 WS-TRANSAKTIONSTYP PIC X(02).
88 TYP-VERKAUF VALUE 'VK'.
88 TYP-RETURE VALUE 'RT'.
88 TYP-ANFRAGE VALUE 'AN'.
88 TYP-STORNO VALUE 'ST'.
PROCEDURE DIVISION.
EVALUATE-PARA.
MOVE 'VK' TO WS-TRANSAKTIONSTYP.
EVALUATE WS-TRANSAKTIONSTYP
WHEN TYP-VERKAUF
DISPLAY 'Verkaufstransaktion wird verarbeitet.'
PERFORM VERARBEITE-VERKAUF
WHEN TYP-RETURE
DISPLAY 'Retoure wird bearbeitet.'
PERFORM VERARBEITE-RETURE
WHEN TYP-ANFRAGE
DISPLAY 'Anfrage wird ausgeführt.'
PERFORM VERARBEITE-ANFRAGE
WHEN 'ST'
DISPLAY 'Stornierung wird durchgeführt.'
PERFORM VERARBEITE-STORNO
WHEN OTHER
DISPLAY 'Unbekannter Transaktionstyp: ' WS-TRANSAKTIONSTYP
PERFORM LOG-FEHLER
END-EVALUATE.
STOP RUN.
VERARBEITE-VERKAUF. DISPLAY 'Logik für Verkauf...'.
VERARBEITE-RETURE. DISPLAY 'Logik für Retoure...'.
VERARBEITE-ANFRAGE. DISPLAY 'Logik für Anfrage...'.
VERARBEITE-STORNO. DISPLAY 'Logik für Storno...'.
LOG-FEHLER. DISPLAY 'Fehlerprotokollierung...'.
EVALUATE kann auch mit mehreren Bedingungen oder Bereichen (THRU) verwendet werden, was es äußerst flexibel macht.

3. Tabellen und Arrays: Die OCCURS Clause für effiziente Datenhaltung
Wenn Sie eine Reihe von gleichartigen Daten verwalten müssen, ist die OCCURS-Klausel in COBOL Ihr Mittel der Wahl. Sie ermöglicht die Definition von Tabellen oder Arrays, die in der WORKING-STORAGE SECTION oder in FILE SECTION (für Satzformate) verwendet werden können.
Wichtige Eigenschaften:
OCCURS n TIMES: Definiert eine feste Anzahl von Wiederholungen eines Datenelements.INDEXED BY: Erstellt einen Index für die Tabelle, der für den Zugriff (SETundSEARCH) und die Iteration (PERFORM VARYING) optimiert ist. Indizes sind binäre Felder, die die relative Position des Elements in der Tabelle speichern.OCCURS n TIMES DEPENDING ON: Ermöglicht die Definition von variablen Tabellen, deren Größe zur Laufzeit bestimmt wird.- Mehrdimensionale Tabellen: Sie können
OCCURS-Klauseln verschachteln, um mehrdimensionale Strukturen zu erzeugen.
Beispiel: Wöchentliche Verkaufsdaten
Stellen Sie sich vor, Sie möchten die täglichen Umsätze und die Anzahl der Transaktionen für eine Woche speichern.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-WOCHENBERICHT.
05 WS-TAGESDATEN OCCURS 7 TIMES
INDEXED BY WS-TAG-IDX.
10 WS-UMSATZ-BETRAG PIC 9(07)V99.
10 WS-TRANSAKTIONEN PIC 9(05).
*
PROCEDURE DIVISION.
TABELLEN-DEMO-PARA.
*> Initialisierung aller Tagesdaten
PERFORM VARYING WS-TAG-IDX FROM 1 BY 1 UNTIL WS-TAG-IDX > 7
MOVE ZEROS TO WS-UMSATZ-BETRAG(WS-TAG-IDX)
MOVE ZEROS TO WS-TRANSAKTIONEN(WS-TAG-IDX)
END-PERFORM.
*
*> Beispiel: Umsatz für den 3. Tag (Mittwoch) erfassen
SET WS-TAG-IDX TO 3.
ADD 250.75 TO WS-UMSATZ-BETRAG(WS-TAG-IDX).
ADD 5 TO WS-TRANSAKTIONEN(WS-TAG-IDX).
DISPLAY 'Umsatz am Tag ' WS-TAG-IDX ': ' WS-UMSATZ-BETRAG(WS-TAG-IDX).
DISPLAY 'Transaktionen am Tag ' WS-TAG-IDX ': ' WS-TRANSAKTIONEN(WS-TAG-IDX).
*
*> Beispiel: Umsatz für den 5. Tag (Freitag) erfassen
SET WS-TAG-IDX TO 5.
ADD 410.20 TO WS-UMSATZ-BETRAG(WS-TAG-IDX).
ADD 8 TO WS-TRANSAKTIONEN(WS-TAG-IDX).
DISPLAY 'Umsatz am Tag ' WS-TAG-IDX ': ' WS-UMSATZ-BETRAG(WS-TAG-IDX).
DISPLAY 'Transaktionen am Tag ' WS-TAG-IDX ': ' WS-TRANSAKTIONEN(WS-TAG-IDX).
*
STOP RUN.
OCCURS ist unverzichtbar für die Verarbeitung von Listen, Berichtszeilen oder komplexen Datenstrukturen, die sich wiederholen. Es ist der Schlüssel zu speicher- und zugriffseffizienten Lösungen auf dem Mainframe.

4. Praxis-Tipp: Fehlerbehandlung und Status-Codes bei Datei-Operationen
Robustheit ist auf dem Mainframe keine Option, sondern eine Notwendigkeit. Fehler bei Dateioperationen können weitreichende Konsequenzen haben. Daher ist eine sorgfältige Fehlerbehandlung unerlässlich. COBOL bietet hierfür die FILE STATUS-Klausel.
Die FILE STATUS-Klausel:
Durch Hinzufügen von FILE STATUS IS ws-file-status zu Ihrer SELECT-Anweisung weisen Sie COBOL an, einen zweistelligen Statuscode in das definierte WORKING-STORAGE-Feld zu schreiben. Dieser Code gibt Auskunft über den Erfolg oder Misserfolg jeder Dateioperation (OPEN, READ, WRITE, CLOSE).
Wichtige Status-Codes (Auszug):
'00': Erfolgreiche Operation.'10': SequentiellesREADerreichte das Dateiende.'30': Permanenter Fehler (z.B. Dateisystemfehler, Hardwaredefekt).'90'-'99': Implementor-definierte Fehler (oft spezifisch für das DMS des BS2000-Systems).
Beispiel: Verbesserte Dateiverarbeitung mit Fehlerprüfung
Dieses Beispiel erweitert unser Dateikopie-Programm um Prüfungen des FILE STATUS nach jeder kritischen Dateioperation.
IDENTIFICATION DIVISION.
PROGRAM-ID. FILEERR.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO INFILE
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-INFILE-STATUS.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-OUTFILE-STATUS.
*
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE
RECORD CONTAINS 80 CHARACTERS
LABEL RECORDS ARE STANDARD
DATA RECORD IS IN-RECORD.
01 IN-RECORD PIC X(80).
*
FD OUTPUT-FILE
RECORD CONTAINS 80 CHARACTERS
LABEL RECORDS ARE STANDARD
DATA RECORD IS OUT-RECORD.
01 OUT-RECORD PIC X(80).
*
WORKING-STORAGE SECTION.
01 WS-INFILE-STATUS PIC X(02).
01 WS-OUTFILE-STATUS PIC X(02).
01 WS-EOF-FLAG PIC X VALUE 'N'.
88 END-OF-FILE VALUE 'Y'.
*
PROCEDURE DIVISION.
MAIN-PARA.
PERFORM 1000-OPEN-FILES.
IF WS-INFILE-STATUS NOT = '00' OR WS-OUTFILE-STATUS NOT = '00'
DISPLAY 'Programmabbruch wegen OPEN-Fehler.'
STOP RUN
END-IF.
*
PERFORM 2000-PROCESS-RECORDS UNTIL END-OF-FILE.
*
PERFORM 3000-CLOSE-FILES.
STOP RUN.
1000-OPEN-FILES.
OPEN INPUT INPUT-FILE.
IF WS-INFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Öffnen von INFILE. Status: ' WS-INFILE-STATUS
END-IF.
*
OPEN OUTPUT OUTPUT-FILE.
IF WS-OUTFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Öffnen von OUTFILE. Status: ' WS-OUTFILE-STATUS
END-IF.
2000-PROCESS-RECORDS.
READ INPUT-FILE
AT END SET END-OF-FILE TO TRUE
END-READ.
*
IF NOT END-OF-FILE
IF WS-INFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Lesen von INFILE. Status: ' WS-INFILE-STATUS
SET END-OF-FILE TO TRUE *> Verarbeitung abbrechen
ELSE
WRITE OUT-RECORD FROM IN-RECORD
IF WS-OUTFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Schreiben nach OUTFILE. Status: ' WS-OUTFILE-STATUS
SET END-OF-FILE TO TRUE *> Verarbeitung abbrechen
END-IF
END-IF
END-IF.
*
3000-CLOSE-FILES.
CLOSE INPUT-FILE.
IF WS-INFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Schließen von INFILE. Status: ' WS-INFILE-STATUS
END-IF.
*
CLOSE OUTPUT-FILE.
IF WS-OUTFILE-STATUS NOT = '00'
DISPLAY 'Fehler beim Schließen von OUTFILE. Status: ' WS-OUTFILE-STATUS
END-IF.
Dieser Ansatz sorgt für Transparenz und ermöglicht es, auf unerwartete Situationen angemessen zu reagieren, sei es durch Protokollierung, Wiederholungsversuche oder einen kontrollierten Abbruch. Vertrauen Sie mir, proaktive Fehlerbehandlung spart Stunden bei der Fehlersuche!

Diese fundamentalen Konzepte von der simplen Dateiverarbeitung über komplexe Logik bis hin zur effizienten Datenhaltung in Tabellen bilden das Rückgrat jeder soliden COBOL-Anwendung auf dem Mainframe. Insbesondere auf BS2000-Systemen, wo jede Ressource zählt, ist es entscheidend, diese Techniken nicht nur zu kennen, sondern auch bewusst und fehlerresistent einzusetzen. Vertiefen Sie Ihr Wissen und tragen Sie so zur Stabilität und Effizienz unserer geschäftskritischen Systeme bei!
