CICS File Control: Complete Guide to READ, WRITE, REWRITE, DELETE, BROWSE

Introduction: CICS File Control and VSAM
CICS File Control is the set of EXEC CICS commands that provides access to VSAM (Virtual Storage Access Method) datasets. In a z/OS CICS environment, virtually all application data — employee records, customer accounts, product catalogs, transaction logs — is stored in VSAM datasets and accessed through CICS File Control. Understanding how to correctly read, write, update, delete, and browse these files is one of the most critical skills for a CICS COBOL developer.
CICS supports three VSAM dataset organisations:
- KSDS (Key-Sequenced Dataset) — records accessed by a key field; the most common type.
- ESDS (Entry-Sequenced Dataset) — records stored in insertion order, accessed by RBA (Relative Byte Address).
- RRDS (Relative Record Dataset) — records accessed by slot number (Relative Record Number).
All three are accessed through the same EXEC CICS commands with slightly different RIDFLD options. This guide focuses on KSDS, which is overwhelmingly the most common in business applications.
Reading a Single Record: EXEC CICS READ
The basic READ command retrieves one record by its primary key:
WORKING-STORAGE SECTION.
01 WS-EMP-KEY PIC X(6).
01 WS-EMP-RECORD.
05 WS-EMP-NO PIC X(6).
05 WS-EMP-NM PIC X(30).
05 WS-EMP-SAL PIC S9(7)V99 COMP-3.
05 WS-EMP-DPT PIC X(4).
01 WS-EMP-LEN PIC S9(4) COMP VALUE +43.
01 WS-RESP PIC S9(8) COMP VALUE ZERO.
01 WS-RESP2 PIC S9(8) COMP VALUE ZERO.
PROCEDURE DIVISION.
READ-EMPLOYEE.
MOVE '000100' TO WS-EMP-KEY
EXEC CICS READ FILE('EMPFILE')
RIDFLD(WS-EMP-KEY)
INTO(WS-EMP-RECORD)
LENGTH(WS-EMP-LEN)
RESP(WS-RESP)
RESP2(WS-RESP2)
END-EXEC
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
PERFORM DISPLAY-EMPLOYEE
WHEN DFHRESP(NOTFND)
MOVE 'EMPLOYEE NOT FOUND.' TO WS-ERR-MSG
WHEN DFHRESP(DISABLED)
MOVE 'FILE IS DISABLED - CONTACT DBA.' TO WS-ERR-MSG
WHEN OTHER
PERFORM HANDLE-FILE-ERROR
END-EVALUATE.Key options on EXEC CICS READ:
| Option | Purpose |
|---|---|
| FILE | CICS file resource name (matches CSD FILE definition) |
| RIDFLD | The key field — must be the exact VSAM key length |
| INTO | Working-storage area to receive the record |
| LENGTH | Length of the INTO area |
| KEYLENGTH | Optional: specify if using a generic (partial) key |
| GENERIC | Read first record whose key starts with RIDFLD value |
| GTEQ | Read record with key >= RIDFLD (rather than exact match) |
| RESP | Capture response code instead of ABEND |
Reading for Update: READ UPDATE / REWRITE / DELETE
To update or delete a record, you must first READ it with the UPDATE option. This places an exclusive lock on the record, preventing other tasks from updating it simultaneously.
*── Read record for update ──────────────────────────────────────
READ-FOR-UPDATE.
EXEC CICS READ FILE('EMPFILE')
RIDFLD(WS-EMP-KEY)
INTO(WS-EMP-RECORD)
LENGTH(WS-EMP-LEN)
UPDATE
RESP(WS-RESP)
END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM HANDLE-READ-ERROR
GO TO END-OF-PROGRAM
END-IF
*── Modify the record in working storage ─────────────────────────
ADD WS-RAISE-AMOUNT TO WS-EMP-SAL
*── Write it back with REWRITE ───────────────────────────────────
REWRITE-EMPLOYEE.
EXEC CICS REWRITE FILE('EMPFILE')
FROM(WS-EMP-RECORD)
LENGTH(WS-EMP-LEN)
RESP(WS-RESP)
END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM HANDLE-REWRITE-ERROR
END-IF.Important rules for READ UPDATE:
- You must issue either REWRITE or DELETE after READ UPDATE. Issuing EXEC CICS RETURN or EXEC CICS SYNCPOINT without REWRITE/DELETE releases the lock without updating the record (changes are discarded).
- The REWRITE does not need RIDFLD — CICS remembers which record was read for update.
- You cannot issue READ UPDATE on an ESDS record (ESDS records can be rewritten in place but not deleted).
Deleting a Record
DELETE-EMPLOYEE.
*── First READ UPDATE the record ────────────────────────────
EXEC CICS READ FILE('EMPFILE')
RIDFLD(WS-EMP-KEY)
INTO(WS-EMP-RECORD)
LENGTH(WS-EMP-LEN)
UPDATE
RESP(WS-RESP)
END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM HANDLE-ERROR
GO TO END-PARA
END-IF
*── Then DELETE ─────────────────────────────────────────────
EXEC CICS DELETE FILE('EMPFILE')
RESP(WS-RESP)
END-EXEC.You can also delete a record without first reading it by providing RIDFLD on the DELETE command directly:
*── Direct delete by key (no prior READ UPDATE needed) ──────────
EXEC CICS DELETE FILE('EMPFILE')
RIDFLD(WS-EMP-KEY)
RESP(WS-RESP)
END-EXEC.Writing a New Record: EXEC CICS WRITE
Use WRITE to add a new record to a VSAM file:
WRITE-NEW-EMPLOYEE.
*── Populate the new record ─────────────────────────────────
MOVE '000999' TO WS-EMP-NO
MOVE 'NEW EMPLOYEE' TO WS-EMP-NM
MOVE 50000.00 TO WS-EMP-SAL
MOVE 'A001' TO WS-EMP-DPT
EXEC CICS WRITE FILE('EMPFILE')
FROM(WS-EMP-RECORD)
LENGTH(WS-EMP-LEN)
RIDFLD(WS-EMP-KEY)
RESP(WS-RESP)
END-EXEC
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
MOVE 'EMPLOYEE ADDED SUCCESSFULLY.' TO WS-MSG
WHEN DFHRESP(DUPREC)
MOVE 'DUPLICATE KEY - EMPLOYEE EXISTS.' TO WS-MSG
WHEN OTHER
PERFORM HANDLE-WRITE-ERROR
END-EVALUATE.Always check for DFHRESP(DUPREC) on WRITE — if a record with the same key already exists in a KSDS, the write fails with this response code.
Browse Operations: STARTBR, READNEXT, READPREV, ENDBR
Sequential browsing through a VSAM KSDS requires four commands working together. This is the standard pattern for building list screens in CICS:
WORKING-STORAGE SECTION.
01 WS-BROWSE-KEY PIC X(6).
01 WS-PAGE-SIZE PIC 9(3) VALUE 12.
01 WS-ROW-COUNT PIC 9(3) VALUE 0.
01 WS-EOF-FLAG PIC X VALUE 'N'.
88 WS-EOF VALUE 'Y'.
PROCEDURE DIVISION.
BROWSE-EMPLOYEES.
MOVE SPACES TO WS-BROWSE-KEY *> Start from beginning
MOVE 'N' TO WS-EOF-FLAG
MOVE ZERO TO WS-ROW-COUNT
*── Position cursor at start of browse ──────────────────────
EXEC CICS STARTBR FILE('EMPFILE')
RIDFLD(WS-BROWSE-KEY)
GTEQ
RESP(WS-RESP)
END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM HANDLE-STARTBR-ERROR
GO TO END-BROWSE
END-IF
*── Read up to WS-PAGE-SIZE records ─────────────────────────
PERFORM UNTIL WS-EOF OR WS-ROW-COUNT = WS-PAGE-SIZE
EXEC CICS READNEXT FILE('EMPFILE')
INTO(WS-EMP-RECORD)
RIDFLD(WS-BROWSE-KEY)
LENGTH(WS-EMP-LEN)
RESP(WS-RESP)
END-EXEC
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
ADD 1 TO WS-ROW-COUNT
PERFORM LOAD-MAP-ROW
WHEN DFHRESP(ENDFILE)
MOVE 'Y' TO WS-EOF-FLAG
WHEN OTHER
PERFORM HANDLE-READ-ERROR
MOVE 'Y' TO WS-EOF-FLAG
END-EVALUATE
END-PERFORM
*── Always end the browse ────────────────────────────────────
EXEC CICS ENDBR FILE('EMPFILE')
RESP(WS-RESP)
END-EXEC.
END-BROWSE.
EXIT.Backward Browsing with READPREV
To implement a "previous page" function, use STARTBR to reposition to the first key of the current page, then use READPREV to walk backwards:
*── Reposition to the FIRST key of current page ─────────────
EXEC CICS STARTBR FILE('EMPFILE')
RIDFLD(WS-PAGE-START-KEY)
EQUAL
RESP(WS-RESP)
END-EXEC
*── Read backwards ──────────────────────────────────────────
PERFORM WS-PAGE-SIZE TIMES
EXEC CICS READPREV FILE('EMPFILE')
INTO(WS-EMP-RECORD)
RIDFLD(WS-BROWSE-KEY)
LENGTH(WS-EMP-LEN)
RESP(WS-RESP)
END-EXEC
IF WS-RESP = DFHRESP(ENDFILE)
EXIT PERFORM
END-IF
PERFORM LOAD-MAP-ROW-REVERSE
END-PERFORM
EXEC CICS ENDBR FILE('EMPFILE') END-EXEC.Unlock Without Update: EXEC CICS UNLOCK
If you read a record with UPDATE but then decide not to update or delete it (for example, the user pressed PF3 to cancel), you must explicitly release the exclusive lock:
*── User cancelled — release the lock without changes ───────────
EXEC CICS UNLOCK FILE('EMPFILE')
RESP(WS-RESP)
END-EXEC.Without EXEC CICS UNLOCK, the exclusive lock is held until the task ends (EXEC CICS RETURN or SYNCPOINT). For long pseudo-conversational interactions, this could lock a record across an entire user think-time period — a significant integrity risk.
Common File Control Response Codes
| DFHRESP Constant | Value | Meaning |
|---|---|---|
| NORMAL | 0 | Command completed successfully |
| NOTFND | 13 | No record matches the key |
| DUPREC | 14 | Duplicate record on WRITE |
| ILLOGIC | 21 | VSAM logical error (check RESP2) |
| LENGERR | 22 | Record longer than INTO area |
| NOSPACE | 28 | VSAM dataset full |
| DISABLED | 84 | File is disabled in CICS |
| ENDFILE | 11 | READNEXT/READPREV reached end/beginning |
| FILENOTFOUND | 12 | FILE resource not installed in CICS |
Key Takeaways
CICS File Control provides a clean, command-level API for VSAM access that abstracts the complexities of VSAM RPLs and ACBs. The core pattern for every file operation is: specify RESP on the command, evaluate the response, handle NOTFND and DUPREC as expected business conditions, and treat all other non-NORMAL responses as unexpected errors requiring logging and graceful failure. Always pair READ UPDATE with REWRITE, DELETE, or UNLOCK to prevent long-held exclusive locks. For sequential access, the STARTBR → READNEXT/READPREV loop → ENDBR pattern is the standard approach for building paged list screens.
To understand how programs call each other within a CICS task, continue with CICS Program Control. For the complete CICS course, visit the CICS Mastery Course.
