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:

  • SELECT und ASSIGN: 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. READ holt den nächsten Datensatz, WRITE fügt einen neuen hinzu. AT END ist 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 (SET und SEARCH) 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': Sequentielles READ erreichte 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!