Chapter 11: Sequential File Processing -- Key Takeaways
Chapter Summary
Sequential file processing is the heart of COBOL programming. The vast majority of batch COBOL programs on mainframes read input files, process records one at a time, and write output files. This chapter covered the complete lifecycle of sequential file handling: defining files in the ENVIRONMENT DIVISION with SELECT...ASSIGN, describing record layouts in the DATA DIVISION with FD entries, and performing I/O operations in the PROCEDURE DIVISION with OPEN, READ, WRITE, and CLOSE. We also examined FILE STATUS codes, the standard sequential read loop pattern, and the connection between COBOL file definitions and JCL DD statements.
The ENVIRONMENT DIVISION's INPUT-OUTPUT SECTION establishes the logical connection between a COBOL file name and an external resource. The SELECT clause assigns a logical file name that is used throughout the program, and the ASSIGN TO clause specifies the external name that maps to a JCL DD statement (on z/OS) or a physical file path (on other platforms). The FILE STATUS clause designates a two-character data item that receives a status code after every I/O operation, enabling the program to detect and handle errors without abending. This chapter emphasized that checking FILE STATUS after every I/O operation is a non-negotiable best practice in professional COBOL programming.
The DATA DIVISION's FILE SECTION contains FD (File Description) entries that describe the record structure of each file. The FD specifies attributes such as record length, blocking factor, and record format. Subordinate to the FD, one or more 01-level record descriptions define the layout of individual fields within each record. In the PROCEDURE DIVISION, files are opened in INPUT, OUTPUT, I-O, or EXTEND mode, records are read with the READ statement and written with the WRITE statement, and files are closed with CLOSE. The READ INTO and WRITE FROM phrases provide a convenient pattern for moving data between file record areas and working-storage, protecting against the re-use of the record buffer on subsequent I/O operations.
Key Concepts
- The SELECT clause in the ENVIRONMENT DIVISION assigns a logical file name that is used in all subsequent references to the file throughout the program.
- ASSIGN TO associates the logical file name with an external name; on z/OS, this maps to a DD name in the JCL that executes the program.
- ORGANIZATION IS SEQUENTIAL is the default file organization and does not need to be explicitly coded, but doing so improves readability.
- FILE STATUS IS followed by a two-character PIC X(02) data item designates a status code variable that is updated after every I/O operation on that file.
- A FILE STATUS value of "00" indicates successful completion; "10" indicates end-of-file on a READ; any other value typically indicates an error condition.
- The FD (File Description) entry in the FILE SECTION describes the physical attributes of a file, including RECORDING MODE (F, V, U), BLOCK CONTAINS, and RECORD CONTAINS clauses.
- The 01-level record description subordinate to the FD defines the field-by-field layout of each record in the file.
- OPEN INPUT opens a file for reading only; OPEN OUTPUT opens for writing (creating or replacing); OPEN I-O opens for both reading and writing; OPEN EXTEND opens for appending to the end.
- READ file-name reads the next sequential record into the file's record area; the AT END clause specifies actions to take when end-of-file is reached.
- READ file-name INTO ws-record reads the next record and simultaneously moves it to a working-storage area, protecting the data from being overwritten by the next READ.
- WRITE record-name writes a record from the file's record area; WRITE record-name FROM ws-record moves data from working-storage to the record area and writes it in a single statement.
- NOT AT END clause in a READ statement specifies actions to take when a record is successfully read, providing a clean alternative to testing FILE STATUS.
- The standard sequential read loop uses a priming READ before a PERFORM UNTIL loop that tests for end-of-file, processes each record, and reads the next record at the bottom of the loop.
- CLOSE releases the file and its associated system resources; failing to close a file can cause data loss for output files as buffered records may not be flushed.
- JCL DD statements on z/OS connect the COBOL program's ASSIGN name to physical datasets, specifying attributes such as DSNAME, DISP, DCB parameters, and SPACE allocation.
Common Pitfalls
- Not checking FILE STATUS after every I/O operation: Omitting FILE STATUS checks allows errors to go undetected, potentially causing the program to process corrupt data or produce incomplete output. Always test the status code after OPEN, READ, WRITE, and CLOSE.
- Forgetting the priming READ: The standard PERFORM UNTIL loop tests for end-of-file at the top of the loop. Without a priming READ before the loop, the end-of-file flag has not been set, and the loop processes whatever data happens to be in the record area, which is typically garbage.
- Writing the record name instead of the FD name on READ: The READ statement takes the file name (the one from the SELECT clause), not the 01-level record name. The WRITE statement, conversely, takes the record name, not the file name. Confusing these is a common compilation error.
- Using WRITE with the file name: WRITE operates on the record name defined under the FD, not the file name. Writing
WRITE OUTPUT-FILEinstead ofWRITE OUTPUT-RECORDcauses a compilation error. - Not initializing the output record before WRITE: If the output record area contains leftover data from a previous operation, fields that were not explicitly moved will contain stale values. Initialize with MOVE SPACES or use WRITE FROM a fully constructed working-storage record.
- Opening an output file in EXTEND mode unintentionally: OPEN EXTEND appends to an existing file rather than replacing it. If the program is intended to create a fresh output file, use OPEN OUTPUT.
- Ignoring the AT END condition on the last READ: When READ hits end-of-file, the record area is undefined. Processing the record area after an AT END condition without checking the status flag processes undefined data.
- Mismatched record lengths between FD and JCL: If the RECORD CONTAINS clause in the FD specifies a length different from the LRECL in the JCL DD statement, the program may abend with a file status error or produce misaligned output.
Quick Reference
* ENVIRONMENT DIVISION file definition
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE
ASSIGN TO INFILE
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-INPUT-STATUS.
SELECT OUTPUT-FILE
ASSIGN TO OUTFILE
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-OUTPUT-STATUS.
* DATA DIVISION file descriptions
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE
RECORDING MODE IS F
BLOCK CONTAINS 0 RECORDS
RECORD CONTAINS 80 CHARACTERS.
01 INPUT-RECORD PIC X(80).
FD OUTPUT-FILE
RECORDING MODE IS F
BLOCK CONTAINS 0 RECORDS
RECORD CONTAINS 132 CHARACTERS.
01 OUTPUT-RECORD PIC X(132).
WORKING-STORAGE SECTION.
01 WS-INPUT-STATUS PIC X(02).
88 INPUT-SUCCESS VALUE "00".
88 INPUT-EOF VALUE "10".
01 WS-OUTPUT-STATUS PIC X(02).
88 OUTPUT-SUCCESS VALUE "00".
01 WS-INPUT-REC.
05 WS-CUST-ID PIC X(10).
05 WS-CUST-NAME PIC X(30).
05 WS-BALANCE PIC S9(7)V99.
05 FILLER PIC X(31).
* PROCEDURE DIVISION standard read loop
PROCEDURE DIVISION.
0000-MAIN.
OPEN INPUT INPUT-FILE
OPEN OUTPUT OUTPUT-FILE
IF NOT INPUT-SUCCESS
DISPLAY "Error opening input: "
WS-INPUT-STATUS
STOP RUN
END-IF
READ INPUT-FILE INTO WS-INPUT-REC
AT END SET INPUT-EOF TO TRUE
END-READ
PERFORM UNTIL INPUT-EOF
PERFORM 1000-PROCESS-RECORD
READ INPUT-FILE INTO WS-INPUT-REC
AT END SET INPUT-EOF TO TRUE
END-READ
END-PERFORM
CLOSE INPUT-FILE
CLOSE OUTPUT-FILE
STOP RUN.
1000-PROCESS-RECORD.
MOVE WS-CUST-NAME TO OUTPUT-RECORD
WRITE OUTPUT-RECORD
IF NOT OUTPUT-SUCCESS
DISPLAY "Write error: " WS-OUTPUT-STATUS
END-IF.
What's Next
Chapter 12 extends file processing to indexed files, specifically VSAM KSDS (Key-Sequenced Data Sets). You will learn how ORGANIZATION IS INDEXED enables direct access to records by key value, how ALTERNATE RECORD KEY supports multiple access paths, and how dynamic access mode combines sequential and random access in a single program. The sequential processing patterns from this chapter serve as the foundation, with indexed files adding the ability to read, update, and delete specific records by key.