Indexed files and VSAM
A sequential file can only be read front to back. That is perfect for a nightly batch run over every account, but useless when a teller asks for one account out of two million. For that you need an indexed file: records are stored in order of a key (account number, policy number, part number) and an index lets the system jump straight to any key.
On z/OS, an indexed COBOL file is a VSAM KSDS (Key-Sequenced Data
Set). The systems team defines it with IDCAMS, giving the key's length and
offset; your program only has to describe it in the SELECT:
IDENTIFICATION DIVISION.
PROGRAM-ID. KSDSDEMO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ACCT-FILE ASSIGN TO ACCTMAST
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS ACCT-ID
FILE STATUS IS WS-FS.
DATA DIVISION.
FILE SECTION.
FD ACCT-FILE.
01 ACCT-REC.
05 ACCT-ID PIC X(6).
05 ACCT-NAME PIC X(20).
WORKING-STORAGE SECTION.
01 WS-FS PIC XX.
PROCEDURE DIVISION.
OPEN OUTPUT ACCT-FILE
MOVE "300100GRACE HOPPER" TO ACCT-REC
WRITE ACCT-REC
MOVE "100100ADA LOVELACE" TO ACCT-REC
WRITE ACCT-REC
CLOSE ACCT-FILE
OPEN INPUT ACCT-FILE
MOVE "300100" TO ACCT-ID
READ ACCT-FILE
DISPLAY ACCT-NAME " STATUS " WS-FS
MOVE "999999" TO ACCT-ID
READ ACCT-FILE
INVALID KEY DISPLAY "999999 NOT FOUND, STATUS " WS-FS
END-READ
CLOSE ACCT-FILE
STOP RUN.
Output:
GRACE HOPPER STATUS 00
999999 NOT FOUND, STATUS 23
The RECORD KEY must be a field inside the record. To read by key you
move the key value into that field, then READ. If no record matches, the
INVALID KEY phrase runs and the status is 23.
Access modes
| ACCESS MODE | What you can do |
|---|---|
SEQUENTIAL (default) |
Read in key order; when loading with OPEN OUTPUT, keys must arrive in ascending order |
RANDOM |
READ / WRITE / REWRITE / DELETE by key value |
DYNAMIC |
Both: random verbs plus START and READ NEXT |
ALTERNATE RECORD KEY IS CUST-CITY WITH DUPLICATES adds a second index,
so you can also find records by a non-unique field. On z/OS that is a VSAM
alternate index (AIX) with a PATH.
Status codes you will meet
| Status | Meaning |
|---|---|
00 |
Success |
02 |
Success, and another record has the same alternate key (IBM) |
10 |
End of file on READ NEXT |
21 |
Key out of sequence (sequential write or REWRITE changed the key) |
22 |
Duplicate key on WRITE (or on a unique alternate key) |
23 |
Record not found (READ, START, REWRITE, DELETE) |
35 |
OPEN INPUT or I-O on a file that does not exist |
Relative files, briefly
A relative file (VSAM RRDS on z/OS) is a row of numbered slots. The key is a slot number held in WORKING-STORAGE, not a field in the record:
IDENTIFICATION DIVISION.
PROGRAM-ID. RELDEMO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SEAT-FILE ASSIGN TO SEATS
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS WS-SEAT-NO
FILE STATUS IS WS-FS.
DATA DIVISION.
FILE SECTION.
FD SEAT-FILE.
01 SEAT-REC PIC X(20).
WORKING-STORAGE SECTION.
01 WS-SEAT-NO PIC 9(3).
01 WS-FS PIC XX.
PROCEDURE DIVISION.
OPEN OUTPUT SEAT-FILE
MOVE 12 TO WS-SEAT-NO
MOVE "ADA LOVELACE" TO SEAT-REC
WRITE SEAT-REC
CLOSE SEAT-FILE
OPEN INPUT SEAT-FILE
MOVE 12 TO WS-SEAT-NO
READ SEAT-FILE
DISPLAY "SEAT 12: " SEAT-REC
MOVE 7 TO WS-SEAT-NO
READ SEAT-FILE
INVALID KEY DISPLAY "SEAT 7 EMPTY, STATUS " WS-FS
END-READ
CLOSE SEAT-FILE
STOP RUN.
This prints SEAT 12: ADA LOVELACE then SEAT 7 EMPTY, STATUS 23.
Relative files are rare in business code; you will see indexed files daily.
On the job
Check FILE STATUS after every OPEN, and treat anything other than the
codes you expect as fatal: display the file name and status, set
RETURN-CODE and stop. A silent 35 or 39 on OPEN is the classic
3 a.m. abend. VSAM also returns a second, "extended" status you can
request with FILE STATUS IS WS-FS WS-VSAM-FS; support staff will ask
for it.