MODULE 8 · SEQUENTIAL FILES · 6/8

OPEN EXTEND and REWRITE

15 min30 XPExercise

OPEN OUTPUT always starts a file from scratch. Two other open modes let you change a file that already exists.

OPEN EXTEND: add to the end

OPEN EXTEND positions you after the last record, and each WRITE adds a new one. Logs, audit trails and "today's rejects" files that build up over a day are typical uses.

What if the file does not exist yet? Normally the OPEN fails with status 35. Declare the file OPTIONAL in the SELECT and a missing file is created instead, with status 05 to tell you so:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. EXTDEMO.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT OPTIONAL AUDIT-FILE ASSIGN TO AUDITLOG
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-AUDIT-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  AUDIT-FILE.
       01  AUDIT-REC          PIC X(30).
       WORKING-STORAGE SECTION.
       01  WS-AUDIT-STATUS    PIC XX.
       PROCEDURE DIVISION.
           OPEN EXTEND AUDIT-FILE
           DISPLAY "OPEN EXTEND: " WS-AUDIT-STATUS
           MOVE "RUN COMPLETED" TO AUDIT-REC
           WRITE AUDIT-REC
           CLOSE AUDIT-FILE
           STOP RUN.

Run twice against a dataset that does not exist yet, it displays OPEN EXTEND: 05 the first time and OPEN EXTEND: 00 the second, and the dataset ends up with two RUN COMPLETED records. Remember that 05 is a success: a status check for this file must accept both 00 and 05. An 88-level with two values does that neatly:

       01  WS-AUDIT-STATUS    PIC XX.
           88  AUDIT-OK       VALUE "00" "05".

OPEN I-O and REWRITE: update in place

OPEN I-O opens a file for both reading and rewriting. REWRITE record replaces the record you just read with the current contents of the record area. The file keeps its records in the same order; only the one record changes.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. RWDEMO.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT CARD-FILE ASSIGN TO CARDS
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-CARD-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  CARD-FILE.
       01  CARD-REC.
           05  CARD-NO        PIC X(4).
           05  CARD-EXPIRY    PIC 9(6).
           05  CARD-STATE     PIC X.
       WORKING-STORAGE SECTION.
       01  WS-CARD-STATUS     PIC XX.
           88  CARD-EOF       VALUE "10".
       PROCEDURE DIVISION.
           OPEN I-O CARD-FILE
           READ CARD-FILE
           PERFORM UNTIL CARD-EOF
               IF CARD-EXPIRY < 202609
                   MOVE "X" TO CARD-STATE
                   REWRITE CARD-REC
                   DISPLAY "EXPIRED " CARD-NO " " WS-CARD-STATUS
               END-IF
               READ CARD-FILE
           END-PERFORM
           CLOSE CARD-FILE
           STOP RUN.

With CARD.MASTER holding

0001202712A
0002202508A
0003202609A
0004201911A

it displays EXPIRED 0002 00 and EXPIRED 0004 00, and afterwards the dataset reads

0001202712A
0002202508X
0003202609A
0004201911X

The rules for REWRITE on a sequential file:

  • The file must be open I-O (otherwise status 49).
  • The last operation on the file must have been a successful READ. A REWRITE with no READ before it fails with status 43.
  • The record must keep its length. You change field contents, never the layout. (With line sequential files, GnuCOBOL returns status 44 if the new text is longer than the line it replaces.)
  • You cannot insert or delete records. For that, you write a new file, which is the subject of the next lesson.

Mainframe reality

On z/OS you would REWRITE a fixed-length disk dataset opened with DISP=OLD (exclusive use). Line sequential files do not exist there; they are used here so you can read the results.

On the job

Updating in place is fast, but there is no undo: if the program abends halfway through, half the file is updated. That is why jobs that REWRITE a file usually back it up in an earlier step, and why the big nightly updates use the old-master / new-master approach instead.

Your task

At the end of each day the warehouse flags items that need reordering.

Stock file, DD name STOCK, line sequential, opened I-O:

Field Picture Positions
STK-ITEM X(6) 1–6
STK-DESC X(20) 7–26
STK-QTY 9(5) 27–31
STK-REORDER 9(5) 32–36
STK-FLAG X: N normal, R on order 37

Reorder log, DD name REORDLOG, line sequential, opened EXTEND. It may not exist yet (first run of the month), so declare it OPTIONAL. Layout (declared in the starter as LOG-REC): item, space, description, space, quantity as Z(4)9.

For every item whose quantity is below its reorder level and which is not already flagged R:

  1. set the flag to R and REWRITE the stock record,
  2. append a record to the reorder log.

At the end display the number flagged:

FLAGGED: 002

If the stock file cannot be opened, display STOCK OPEN FAILED: and the status, and stop with return code 12. Remember that 05 is a successful OPEN for an optional file.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.