Chapter 13: Relative File Processing and Advanced File Techniques -- Key Takeaways

Chapter Summary

Relative file organization provides direct access to records based on their numeric position within a file, offering a middle ground between the simplicity of sequential files and the key-based flexibility of indexed files. This chapter explored the mechanics of ORGANIZATION IS RELATIVE, the RELATIVE KEY clause, and the three access modes (SEQUENTIAL, RANDOM, and DYNAMIC) that govern how records are read and written. Unlike indexed files where access is based on meaningful key values, relative files use the record's ordinal slot number as its address, making them ideal for scenarios where records map naturally to a numeric identifier such as an account number range or a fixed-size lookup table.

On the mainframe, relative file organization maps to VSAM Relative Record Data Sets (RRDS), where each record occupies a fixed-length slot identified by its relative record number (RRN). We examined how to define the RRDS in JCL, how the COBOL runtime translates RELATIVE KEY values into physical slot addresses, and the implications of empty slots for sequential retrieval. The START statement was introduced for positioning within a relative file during dynamic access, allowing programs to begin sequential reads from any arbitrary slot position rather than always starting at record number one.

The chapter also expanded into advanced file techniques that apply across all file organizations. The LINAGE clause provides page-oriented output control for printed reports, specifying logical page dimensions including body lines, footing areas, and top and bottom margins. Multi-file processing patterns were discussed, showing how programs can read from multiple input files simultaneously and merge or correlate their data. File sharing considerations and the use of the LOCK MODE clause were introduced for environments where multiple programs or threads may access the same file concurrently.

Key Concepts

  • ORGANIZATION IS RELATIVE declares a file whose records are identified by their ordinal position, stored in fixed-length slots numbered starting from 1.
  • The RELATIVE KEY clause in the SELECT statement names a working-storage integer that holds the relative record number (RRN) for random and dynamic access operations.
  • ACCESS MODE IS SEQUENTIAL processes relative file records in slot order from beginning to end, including the ability to skip empty slots automatically.
  • ACCESS MODE IS RANDOM uses the RELATIVE KEY value to read, write, rewrite, or delete a specific record by its slot number in a single I/O operation.
  • ACCESS MODE IS DYNAMIC combines sequential and random access in the same program, allowing positioned reads via START followed by sequential READ NEXT operations.
  • The START statement positions the file pointer to a specific relative record number, using relational operators (EQUAL TO, GREATER THAN, NOT LESS THAN) to find the target slot.
  • VSAM RRDS is the mainframe implementation of relative file organization, requiring JCL DD statements and IDCAMS DEFINE CLUSTER with NUMBERED to create the data set.
  • Empty slots occur in relative files when records are deleted (DELETE statement) or when records are written to non-contiguous slot positions, leaving gaps in the file.
  • The LINAGE clause in the FD entry defines logical page structure for print files, specifying LINAGE IS n LINES, WITH FOOTING AT, LINES AT TOP, and LINES AT BOTTOM.
  • LINAGE-COUNTER is a special register automatically maintained by the runtime that tracks the current line position within the page body, enabling programmatic page-break logic.
  • Multi-file processing requires careful coordination of FILE STATUS fields, AT END conditions, and matching logic when reading from two or more input files simultaneously.
  • The LOCK MODE clause (IS AUTOMATIC or IS MANUAL) controls file-sharing behavior in multi-user or multi-threaded environments, preventing concurrent update conflicts.
  • The WRITE statement with INVALID KEY detects attempts to write to an already-occupied slot, while the READ statement with INVALID KEY handles requests for nonexistent relative record numbers.
  • DELETE removes a record from a relative file by marking its slot as empty; the slot can later be reused by writing a new record to the same RRN.

Common Pitfalls

  • Forgetting to initialize the RELATIVE KEY before I/O: The relative key data item must contain a valid record number before every RANDOM read, write, rewrite, or delete. An uninitialized key containing zero or garbage will cause an INVALID KEY condition or unpredictable behavior.
  • Assuming relative record numbers start at zero: COBOL relative record numbers begin at 1, not 0. Writing to RRN 0 will trigger an INVALID KEY condition.
  • Not handling empty slots during sequential reads: When reading a relative file sequentially, the runtime automatically skips empty slots, but programs that assume contiguous records may miscount or produce incorrect totals.
  • Using a RELATIVE KEY data item that is too small: If the key field is defined as PIC 9(3), the file can only address 999 slots. Records beyond that range cannot be accessed without redefining the key field with more digits.
  • Confusing relative files with indexed files: Relative files do not support alternate keys, and the record number has no semantic meaning embedded in the record data itself. Trying to use ALTERNATE RECORD KEY with a relative file will cause a compilation error.
  • Neglecting FILE STATUS checks after each I/O: Relying solely on INVALID KEY and AT END misses other error conditions such as file not found (status 35) or permanent I/O error (status 30). Always check the two-byte file status field.
  • LINAGE miscalculations: The LINAGE value specifies body lines only, not the total physical page. The total page length is LINAGE + LINES AT TOP + LINES AT BOTTOM. Incorrect values cause text to overflow onto the next physical page unpredictably.
  • Not accounting for LOCK MODE in production: Omitting LOCK MODE when multiple batch jobs or CICS transactions access the same file can cause data corruption or deadlocks that are difficult to reproduce and diagnose.

Quick Reference

      * SELECT entry for a relative file
           SELECT REL-FILE
               ASSIGN TO "RELDATA"
               ORGANIZATION IS RELATIVE
               ACCESS MODE IS DYNAMIC
               RELATIVE KEY IS WS-RRN
               FILE STATUS IS WS-FILE-STATUS.

      * Working-storage for relative key and file status
       01  WS-RRN               PIC 9(06).
       01  WS-FILE-STATUS        PIC XX.

      * FD entry
       FD  REL-FILE.
       01  REL-RECORD            PIC X(100).

      * Random READ by relative record number
           MOVE 42 TO WS-RRN
           READ REL-FILE
               INVALID KEY
                   DISPLAY "Record not found: " WS-RRN
               NOT INVALID KEY
                   DISPLAY "Record retrieved"
           END-READ

      * Random WRITE to a specific slot
           MOVE 42 TO WS-RRN
           WRITE REL-RECORD
               INVALID KEY
                   DISPLAY "Slot already occupied: " WS-RRN
           END-WRITE

      * DELETE a record from a relative file
           MOVE 42 TO WS-RRN
           DELETE REL-FILE
               INVALID KEY
                   DISPLAY "Cannot delete: " WS-RRN
           END-DELETE

      * START and sequential READ NEXT
           MOVE 100 TO WS-RRN
           START REL-FILE KEY IS >= WS-RRN
               INVALID KEY
                   DISPLAY "No record at or after: " WS-RRN
           END-START
           READ REL-FILE NEXT RECORD
               AT END
                   DISPLAY "End of file"
           END-READ

      * LINAGE clause for print file
       FD  PRINT-FILE
           LINAGE IS 54 LINES
           WITH FOOTING AT 50
           LINES AT TOP 3
           LINES AT BOTTOM 3.

What's Next

Chapter 14 introduces Sort and Merge operations, which are fundamental to batch processing on the mainframe. You will learn how to use the SORT statement to reorder records from one or more input files, how INPUT PROCEDURE and OUTPUT PROCEDURE give you programmatic control over records entering and leaving the sort process, and how the MERGE statement combines pre-sorted files into a single ordered output. The chapter also covers integration with external sort utilities such as DFSORT and SyncSort, and the JCL SORTWK DD statements required to allocate sort work space on z/OS.