Relative & Indexed Files (VSAM)
22.1 File organizations compared
VSAM type (z/OS) ESDS (Entry-Sequenced) or QSAM Sequential (ESDS also by RBA) Logs, transaction journals RRDS (Relative Record) By record number 1..n
Slot-based tables, direct lookup by number KSDS (Key-Sequenced)
By key, sequentially in key order, or both Master files: customers, accounts, products
22.2 Indexed file operations
To read by the alternate key, move a value to ACCT-NAME and code READ ACCT-FILE KEY IS ACCT-NAME; READ NEXT then continues in name order.
With ACCESS MODE IS SEQUENTIAL, records must be written in ascending key order (status 21 otherwise). With DYNAMIC or RANDOM they can be written in any order (shown above).
INVALID KEY handles statuses 2x (duplicate key, not found); check FILE STATUS for everything else.
In SEQUENTIAL access, REWRITE/DELETE require a preceding successful READ (status 43 otherwise).
GnuCOBOL needs an indexed-file handler (Berkeley DB, VBISAM, or LMDB) — cobc --info shows which one is built in.
IDENTIFICATION DIVISION.
PROGRAM-ID. ACCTIDX.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ACCT-FILE ASSIGN TO "accounts.dat"
ORGANIZATION IS INDEXED
ACCESS MODE IS DYNAMIC
RECORD KEY IS ACCT-ID
ALTERNATE RECORD KEY IS ACCT-NAME WITH DUPLICATES
FILE STATUS IS WS-FS.
DATA DIVISION.
FILE SECTION.
FD ACCT-FILE.
01 ACCT-REC.
05 ACCT-ID PIC 9(6).
05 ACCT-NAME PIC X(20).
05 ACCT-BALANCE PIC S9(9)V99 COMP-3.
WORKING-STORAGE SECTION.
01 WS-FS PIC XX.
01 WS-EOF PIC X VALUE "N".
01 ED-BAL PIC -ZZZ,ZZZ,ZZ9.99.
PROCEDURE DIVISION.
0000-MAIN.
* Create the file and load three records
OPEN OUTPUT ACCT-FILE
MOVE 100200 TO ACCT-ID MOVE "BAKER" TO ACCT-NAME
MOVE 1500.00 TO ACCT-BALANCE PERFORM 8000-WRITE
MOVE 100100 TO ACCT-ID MOVE "ADAMS" TO ACCT-NAME
MOVE 250.50 TO ACCT-BALANCE PERFORM 8000-WRITE
MOVE 100300
…100100 ADAMS 250.50
100200 BAKER 1,600.0022.3 Relative files
The RELATIVE KEY must be defined in WORKING-STORAGE (not in the record) and holds the record slot number.
SELECT SEAT-FILE ASSIGN TO "seats.dat"
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS WS-SEAT-NO
FILE STATUS IS WS-FS.
* ...
WORKING-STORAGE SECTION.
01 WS-SEAT-NO PIC 9(4).
* ...
MOVE 17 TO WS-SEAT-NO
READ SEAT-FILE
INVALID KEY DISPLAY "SEAT 17 EMPTY"
END-READ22.4 Defining VSAM datasets on z/OS (IDCAMS)
INDEXED = KSDS, NONINDEXED = ESDS, NUMBERED = RRDS, LINEAR = LDS.
KEYS(length offset) — offset is 0-based.
Alternate keys need DEFINE ALTERNATEINDEX, DEFINE PATH, and BLDINDEX; in JCL the path's DD name is the base DD name with a digit appended (e.g., ACCTFILE → ACCTFIL1).
In COBOL, an ESDS is ORGANIZATION SEQUENTIAL with ASSIGN TO AS-ddname; a KSDS is ORGANIZATION INDEXED; an RRDS is ORGANIZATION RELATIVE.
VSAM-specific extended status: add a second field FILE STATUS IS WS-FS WS-VSAM-FS where WS-VSAM-FS is a 6-byte group of return code, function code, and feedback code (each PIC 9(2) COMP).
Other IDCAMS commands: REPRO (copy/load), PRINT (dump records), LISTCAT (catalog info), VERIFY.
//DEFKSDS JOB (ACCT),'DEFINE KSDS',CLASS=A,MSGCLASS=X
//STEP1 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE USER01.ACCOUNT.KSDS CLUSTER PURGE
SET MAXCC = 0
DEFINE CLUSTER (NAME(USER01.ACCOUNT.KSDS) -
INDEXED -
KEYS(6 0) -
RECORDSIZE(32 32) -
FREESPACE(10 10) -
CYLINDERS(1 1)) -
DATA (NAME(USER01.ACCOUNT.KSDS.DATA)) -
INDEX (NAME(USER01.ACCOUNT.KSDS.INDEX))
/*