Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

COBOL  Module 8 – Indexed and relative files (VSAM concepts)

Indexed files: keys, access modes and INVALID KEY

Define COBOL indexed files with prime and alternate keys, read them by key or in key order, and handle INVALID KEY with statuses 21, 22, 23 and 43.

  • Intermediate
  • 15 minutes
  • Examples run with GnuCOBOL 3.2 and Python 3.14.8
  • By MySmartCoPilot
Free lesson, Pro answers: 15 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Define an indexed file with a prime record key and an alternate key that allows duplicates
  • Read, rewrite, delete and browse records by key in random, sequential and dynamic access
  • Handle INVALID KEY and the file statuses 21, 22, 23 and 43, and predict where status 02 differs between compilers
  • Map an indexed file onto a VSAM key-sequenced data set, its alternate index and its path

Before you start

What you’ll learn · Before you start

What you will learn

  • Define an indexed file with a prime record key and an alternate key that allows duplicates
  • Read, rewrite, delete and browse records by key in random, sequential and dynamic access
  • Handle INVALID KEY and the file statuses 21, 22, 23 and 43, and predict where status 02 differs between compilers
  • Map an indexed file onto a VSAM key-sequenced data set, its alternate index and its path

Before you start

On this page

A change of address touches one account, yet in a sequential file the program reads past every record before it and writes a new copy of the whole file. An indexed file finds account AC0003 by its key, rewrites that one record, and answers status 23 when an account such as AC0004 is not there.

This lesson builds a five-account indexed file with GnuCOBOL and runs every keyed statement on it: WRITE, READ, REWRITE, DELETE, START and READ NEXT, by account number and by city. Every run shows the FILE STATUS it set, two of them where GnuCOBOL 3.2 and IBM’s Enterprise COBOL disagree, and the last section maps the file onto the VSAM data set it becomes on z/OS.

An indexed file stores records by key and refuses a duplicate

The accounts arrive in the order the branches sent them, not in account order, and the last line repeats AC0002 with a different balance. Each line is one record: the account number, the holder’s name, the city and a balance of nine digits with two decimals.

accounts.txt: six lines in the order the branches sent them Text · accounts.txt
AC0007SUNITA RAO      PUNE      000120000
AC0002MOHAN DAS       NAGPUR    000045050
AC0005FARHAN ALI      PUNE      000310000
AC0001ANITA DESHMUKH  NAGPUR    000250000
AC0003RAVI KUMAR      PUNE      000150000
AC0002MOHAN DAS       NAGPUR    000099999

acctload.cob reads the lines and writes each one to an indexed file: A file whose records are kept in the order of a key, so a program can read one record by its key or read them all in key order. ORGANIZATION IS INDEXED; on z/OS it is a VSAM key-sequenced data set.. Its SELECT entry says what the file is. RECORD KEY IS AC-NUMBER names the prime record key: The key that RECORD KEY names in an indexed file. Its values must be unique, they set the order of the records, and a random READ, REWRITE or DELETE finds its record by it., whose values, IBM’s RECORD KEY page says, “must be unique among records in the file”. ALTERNATE RECORD KEY IS AC-CITY names a second key, the alternate record key: A second key of an indexed file, named by ALTERNATE RECORD KEY, by which the same records can also be read and browsed. WITH DUPLICATES lets several records share one value., and WITH DUPLICATES lets several accounts share a city.

acctload.cob: every line written to an indexed file, its status shown COB · acctload.cob
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCTLOAD.
      * Loads the indexed account file from a text file of accounts,
      * one line each, and prints the FILE STATUS of every WRITE.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-IN ASSIGN TO "ACCTIN"
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS IN-STATUS.
           SELECT ACCT-FILE ASSIGN TO "ACCTS"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS RANDOM
               RECORD KEY IS AC-NUMBER
               ALTERNATE RECORD KEY IS AC-CITY WITH DUPLICATES
               FILE STATUS IS AC-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-IN.
       01  IN-REC               PIC X(41).
       FD  ACCT-FILE.
       01  ACCT-REC.
           05  AC-NUMBER        PIC X(6).
           05  AC-NAME          PIC X(16).
           05  AC-CITY          PIC X(10).
           05  AC-BALANCE       PIC 9(7)V99.
       WORKING-STORAGE SECTION.
       01  IN-STATUS            PIC XX.
       01  AC-STATUS            PIC XX.
       PROCEDURE DIVISION.
           OPEN INPUT ACCT-IN
           OPEN OUTPUT ACCT-FILE
           DISPLAY "OPEN OUTPUT   " AC-STATUS
           READ ACCT-IN
           PERFORM UNTIL IN-STATUS NOT = "00"
               MOVE IN-REC TO ACCT-REC
               WRITE ACCT-REC
                   INVALID KEY
                       DISPLAY "WRITE " AC-NUMBER "  " AC-STATUS
                           "  not written: the key is taken"
                   NOT INVALID KEY
                       DISPLAY "WRITE " AC-NUMBER "  " AC-STATUS
               END-WRITE
               READ ACCT-IN
           END-PERFORM
           CLOSE ACCT-IN ACCT-FILE
           STOP RUN.
Clause What it tells the run time
ORGANIZATION IS INDEXED the records are kept in the order of their keys
ACCESS MODE IS RANDOM each statement names its record by the key field
RECORD KEY IS AC-NUMBER the prime key, unique in the file
ALTERNATE RECORD KEY IS AC-CITY WITH DUPLICATES a second key, which may repeat
FILE STATUS IS AC-STATUS two characters set by every statement

OPEN OUTPUT creates the file empty, and each WRITE stores the record under the key in AC-NUMBER, in any order. Run the load:

Five accounts written, the sixth refused with status 22 Python · load_session.py
from session import files, run

# Six account lines, in the order the branches sent them, written to an indexed file keyed by account number.
files("acctload.cob", "accounts.txt")
run("""
cobc -x acctload.cob
DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload
ls accounts.idx*
cobc --info | grep 'indexed file'
""")

Output

$ cobc -x acctload.cob
$ DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload
OPEN OUTPUT   00
WRITE AC0007  00
WRITE AC0002  00
WRITE AC0005  00
WRITE AC0001  00
WRITE AC0003  00
WRITE AC0002  22  not written: the key is taken
$ ls accounts.idx*
accounts.idx
accounts.idx.1
$ cobc --info | grep 'indexed file'
indexed file handler     : BDB

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 load_session.py

Five WRITEs returned 00. The second AC0002 returned 22, the invalid key condition: What a keyed WRITE, READ, REWRITE, DELETE or START reports when it cannot place or find a record: a status starting with 2, such as 22 for a taken key or 23 for a missing one. The INVALID KEY phrase runs then. for a key that is taken, so the INVALID KEY phrase ran and the WRITE stored nothing: the first AC0002 kept its balance of 450.50. The listing shows two files. accounts.idx holds the records under their account numbers, and accounts.idx.1 holds the city key; cobc names the handler that wrote them, BDB, the Berkeley DB library. Copy and back up the two files together, because neither is the whole file. Step through the load:

Interactive · step by step Six lines written to an indexed file, one WRITE at a time Step through the load. Watch where each record goes in accounts.idx, what goes into accounts.idx.1, and the status of each WRITE.
Six lines written to an indexed file, one WRITE at a time, step 6 of 6. Showing accounts.txt (line 6: AC0002 again), WRITE ACCT-REC, AC-STATUS (22: the key is taken), accounts.idx (AC0001 to AC0007, 5 records), accounts.idx.1 (NAGPUR 2, PUNE 3).READ and MOVEby its keythe city keyaccounts.txtline 6: AC0002 againWRITE ACCT-RECrandom accessAC-STATUS22: the key is takenaccounts.idxAC0001 to AC0007, 5 recordsaccounts.idx.1NAGPUR 2, PUNE 3

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The first line. READ brings the first line, AC0007 SUNITA RAO of PUNE, into IN-REC, and MOVE copies it into ACCT-REC, the record area of the indexed file.
  2. Placed by its key. WRITE stores the record under its prime key, AC0007. The program never says where the record goes; the key does, so the file is in key order whatever order the lines come in.
  3. The city key. The same WRITE adds the alternate key, PUNE, with the account number it belongs to, AC0007, to the second file, accounts.idx.1. AC-STATUS is 00.
  4. Lines 2 to 5. AC0002, AC0005, AC0001 and AC0003 arrive out of order. Each WRITE puts its record where its key belongs, so the file now reads AC0001, AC0002, AC0003, AC0005, AC0007, each WRITE with status 00.
  5. A key that is taken. The sixth line is AC0002 again, with a balance of 999.99. Its prime key is already in the file, so WRITE stores nothing, sets status 22 and runs the INVALID KEY phrase.
  6. What the load left. Five records in key order in accounts.idx, and their cities in accounts.idx.1. The first AC0002 kept its balance of 450.50, because a WRITE never replaces a record.

Random access reads, rewrites and deletes one record by its key

In random access, IBM’s ACCESS MODE page says, “the value placed in a record key data item specifies the record to be accessed”. acctmaint.cob opens the loaded file I-O, for input and output, and puts a key in AC-NUMBER before every statement:

acctmaint.cob: READ, REWRITE and DELETE by account number COB · acctmaint.cob
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCTMAINT.
      * Reads, changes and deletes accounts by their number, in random
      * access, and prints the FILE STATUS of each statement.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-FILE ASSIGN TO "ACCTS"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS RANDOM
               RECORD KEY IS AC-NUMBER
               ALTERNATE RECORD KEY IS AC-CITY WITH DUPLICATES
               FILE STATUS IS AC-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-FILE.
       01  ACCT-REC.
           05  AC-NUMBER        PIC X(6).
           05  AC-NAME          PIC X(16).
           05  AC-CITY          PIC X(10).
           05  AC-BALANCE       PIC 9(7)V99.
       WORKING-STORAGE SECTION.
       01  AC-STATUS            PIC XX.
       PROCEDURE DIVISION.
           OPEN I-O ACCT-FILE
           MOVE "AC0004" TO AC-NUMBER
           READ ACCT-FILE
               INVALID KEY
                   DISPLAY "READ AC0004     " AC-STATUS
                       "  no such account"
           END-READ
           MOVE "AC0003" TO AC-NUMBER
           READ ACCT-FILE
               NOT INVALID KEY
                   DISPLAY "READ AC0003     " AC-STATUS
                       "  [" ACCT-REC "]"
           END-READ
           MOVE "MUMBAI" TO AC-CITY
           REWRITE ACCT-REC
           DISPLAY "REWRITE AC0003  " AC-STATUS "  city now MUMBAI"
      *    The mistake: a REWRITE of AC0005 with no READ before it.
           INITIALIZE ACCT-REC
           MOVE "AC0005" TO AC-NUMBER
           MOVE "MUMBAI" TO AC-CITY
           REWRITE ACCT-REC
           DISPLAY "REWRITE AC0005  " AC-STATUS "  no READ before it"
           READ ACCT-FILE
           DISPLAY "READ AC0005     " AC-STATUS "  [" ACCT-REC "]"
           MOVE "AC0009" TO AC-NUMBER
           DELETE ACCT-FILE RECORD
               INVALID KEY
                   DISPLAY "DELETE AC0009   " AC-STATUS
                       "  no such account"
           END-DELETE
           MOVE "AC0001" TO AC-NUMBER
           DELETE ACCT-FILE RECORD
           DISPLAY "DELETE AC0001   " AC-STATUS
           READ ACCT-FILE
           DISPLAY "READ AC0001     " AC-STATUS "  deleted"
           CLOSE ACCT-FILE
           STOP RUN.
Two missing keys, a change of city, and a REWRITE that wiped a record Python · maint_session.py
from session import files, run

# The loaded file read, changed and deleted by key in random access.
files("acctload.cob", "acctmaint.cob", "accounts.txt")
run("""
cobc -x acctload.cob && cobc -x acctmaint.cob
DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
DD_ACCTS=accounts.idx ./acctmaint
""")

Output

$ cobc -x acctload.cob && cobc -x acctmaint.cob
$ DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
$ DD_ACCTS=accounts.idx ./acctmaint
READ AC0004     23  no such account
READ AC0003     00  [AC0003RAVI KUMAR      PUNE      000150000]
REWRITE AC0003  00  city now MUMBAI
REWRITE AC0005  00  no READ before it
READ AC0005     00  [AC0005                MUMBAI    000000000]
DELETE AC0009   23  no such account
DELETE AC0001   00
READ AC0001     23  deleted

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 maint_session.py

READ AC0004 returned 23, and its INVALID KEY phrase said so: there is no such account. READ AC0003 returned 00 with the whole record, RAVI KUMAR of PUNE, and after MUMBAI was moved into AC-CITY, REWRITE replaced the stored record with the changed one. DELETE AC0009 returned 23, DELETE AC0001 returned 00, and the READ of AC0001 after it returned 23, because the record is gone. Neither DELETE needed a READ first.

Status IBM’s meaning Where the runs set it
00 successful completion every statement that found or placed its record
22 a duplicate prime key, or an alternate key without DUPLICATES the second WRITE of AC0002
23 random access to a record that does not exist READ AC0004, DELETE AC0009

The REWRITE of AC0005 is the line to remember. Nothing read AC0005 first: the program cleared the record area with INITIALIZE and moved in only the key and the new city, so REWRITE replaced FARHAN ALI and the balance of 3,100.00 with spaces and zeros. It returned 00, because a REWRITE in random access needs no READ: it writes the whole record area under the key it holds.

A REWRITE of fields that were never read

Wrong: MOVE the key and the one changed field into the record, then REWRITE, which writes every other field as the record area holds it, blanks after an INITIALIZE or another account’s data, and returns 00. Right: READ the record by its key, check for 00, change the field in the record the READ returned, then REWRITE it and check the status again.

Checkpoint

Check: Prime keys, the load and status 22 · READ, REWRITE and DELETE by key

  1. Question 1 of 2 A seventh line, AC0003 VIJAY NAIR of KOCHI, is added to accounts.txt and acctload.cob loads the file again. What happens to that line?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: WRITE returns 22, the INVALID KEY phrase runs, and RAVI KUMAR's record stays as it is

    The prime record key decides where a record goes and must be unique. A WRITE of a key that is already in the file leaves the file as it was and reports the invalid key condition, status 22.

  2. Question 2 of 2 In acctmaint.cob, the REWRITE of AC0005 turned FARHAN ALI and 3,100.00 into spaces and zeros, with status 00. Which change keeps the name and balance?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: READ AC0005 first, move MUMBAI into the record the READ returned, then REWRITE it

    In random access a REWRITE needs no READ before it. It replaces the record whose key is in the key field with the whole record area, so a program that changes one field must read the record first.

A report of every account reads the whole file in account order. With dynamic access: ACCESS MODE IS DYNAMIC: in the same run, a program may read an indexed or relative file by key and also read on through it in order with START and READ NEXT., a program may do both in one run: read by key, and read on in key order. IBM describes START as a way of “positioning within an indexed or relative file for subsequent sequential record retrieval”: it reads nothing itself, and READ NEXT then reads the next record from the place it set.

acctbrowse.cob: a browse from the start, then START on missing keys COB · acctbrowse.cob
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCTBROWSE.
      * Browses the account file in key order with START and READ
      * NEXT, then tries two START statements on a key that is not
      * in the file.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-FILE ASSIGN TO "ACCTS"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS DYNAMIC
               RECORD KEY IS AC-NUMBER
               ALTERNATE RECORD KEY IS AC-CITY WITH DUPLICATES
               FILE STATUS IS AC-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-FILE.
       01  ACCT-REC.
           05  AC-NUMBER        PIC X(6).
           05  AC-NAME          PIC X(16).
           05  AC-CITY          PIC X(10).
           05  AC-BALANCE       PIC 9(7)V99.
       WORKING-STORAGE SECTION.
       01  AC-STATUS            PIC XX.
       PROCEDURE DIVISION.
           OPEN INPUT ACCT-FILE
           MOVE LOW-VALUES TO AC-NUMBER
           START ACCT-FILE KEY IS GREATER THAN AC-NUMBER
           DISPLAY "START > LOW-VALUES  " AC-STATUS
           PERFORM READ-NEXT
           PERFORM UNTIL AC-STATUS NOT = "00"
               DISPLAY "READ NEXT           " AC-STATUS "  " AC-NUMBER
                   " " AC-NAME
               PERFORM READ-NEXT
           END-PERFORM
           DISPLAY "READ NEXT           " AC-STATUS "  the end"
           MOVE "AC0006" TO AC-NUMBER
           START ACCT-FILE KEY IS EQUAL TO AC-NUMBER
           DISPLAY "START = AC0006      " AC-STATUS
           MOVE "AC0004" TO AC-NUMBER
           START ACCT-FILE KEY IS NOT LESS THAN AC-NUMBER
           DISPLAY "START >= AC0004     " AC-STATUS
           PERFORM READ-NEXT
           DISPLAY "READ NEXT           " AC-STATUS "  " AC-NUMBER
               " " AC-NAME
           CLOSE ACCT-FILE
           STOP RUN.
       READ-NEXT.
           READ ACCT-FILE NEXT RECORD.
Five accounts in key order, then status 23 and a START that lands on AC0005 Python · browse_session.py
from session import files, run

# The loaded file browsed in key order with START and READ NEXT, then two START statements on missing keys.
files("acctload.cob", "acctbrowse.cob", "accounts.txt")
run("""
cobc -x acctload.cob && cobc -x acctbrowse.cob
DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
DD_ACCTS=accounts.idx ./acctbrowse
""")

Output

$ cobc -x acctload.cob && cobc -x acctbrowse.cob
$ DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
$ DD_ACCTS=accounts.idx ./acctbrowse
START > LOW-VALUES  00
READ NEXT           00  AC0001 ANITA DESHMUKH
READ NEXT           00  AC0002 MOHAN DAS
READ NEXT           00  AC0003 RAVI KUMAR
READ NEXT           00  AC0005 FARHAN ALI
READ NEXT           00  AC0007 SUNITA RAO
READ NEXT           10  the end
START = AC0006      23
START >= AC0004     00
READ NEXT           00  AC0005 FARHAN ALI

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 browse_session.py

LOW-VALUES is below every key, so START KEY IS GREATER THAN LOW-VALUES put the place before AC0001. The READ NEXT loop then read AC0001, AC0002, AC0003, AC0005 and AC0007, the order of the keys, although AC0007 was written first, and the READ NEXT after the last account returned 10, the end of the file. START KEY IS EQUAL TO AC0006 returned 23: IBM’s START page says that when “the comparison is not satisfied by any record in the file, an invalid key condition exists”. KEY IS NOT LESS THAN AC0004 found no AC0004 to stop at, so it set the place at the next key, AC0005. Step through the browse:

Interactive · stage by stage START and READ NEXT through the account file Step down the column. START only sets a place in key order; each READ NEXT then reads the next record from that place.
START and READ NEXT through the account file, step 7 of 7. Showing OPEN INPUT ACCT-FILE, START KEY > LOW-VALUES (KEY >= AC0004: status 00), READ NEXT RECORD (AC0005, status 00), Status 00?, Display the account, Status 10. In focus: START KEY > LOW-VALUES, READ NEXT RECORD.read onnot 00OPEN INPUT ACCT-FILEaccess mode dynamicSTART KEY > LOW-VALUESKEY >= AC0004: status 00READ NEXT RECORDAC0005, status 00Status 00?tested after every READ NEXTDisplay the accountthen read the next oneStatus 10no record after the last

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. Open. OPEN INPUT opens the file in dynamic access, so the program may read by key and also read on in key order.
  2. Set the place. LOW-VALUES is below every key, so START KEY IS GREATER THAN LOW-VALUES puts the file's place before AC0001. START reads no record; it sets status 00.
  3. The first READ NEXT. READ NEXT reads the record after that place, AC0001 ANITA DESHMUKH, with status 00. It is the lowest key, although it was the fourth line written.
  4. Read on in key order. The loop displays each account and reads the next one, AC0002, AC0003, AC0005 and AC0007, in the order of their keys, not the order they arrived in.
  5. Past the last record. The READ NEXT after AC0007 finds no record and sets status 10. The test leaves the loop, as it does for a sequential file.
  6. A START on a missing key. START KEY IS EQUAL TO AC0006 asks for a record that is not in the file, so it sets status 23 and leaves no place to read from.
  7. NOT LESS THAN finds the next key. START KEY IS NOT LESS THAN AC0004 has no AC0004 to stop at, so it sets its place at the next key, AC0005, and the READ NEXT after it reads FARHAN ALI.

ACCESS MODE Reads Writes and changes
SEQUENTIAL, the default READ gives the next record in key order WRITE in ascending key order; REWRITE and DELETE the record just read
RANDOM READ by the key in the key field WRITE, REWRITE and DELETE by key, in any order
DYNAMIC READ by key, and START with READ NEXT in key order as in random access

Key idea

START only sets a place in key order and reports 23 when no key satisfies it; READ NEXT reads from that place, in the order of the keys, until status 10.

Sequential access writes in key order and rewrites only what it read

Sequential access makes a promise about order. IBM’s ACCESS MODE page says the records “are accessed in the sequence of ascending record key values”, and the file status table holds the run to it. seqrules.cob opens a new file OUTPUT in sequential access and writes AC0003, AC0001 and AC0005, in that order. Then it tries the two ways a REWRITE can go wrong:

seqrules.cob: three WRITEs, then two REWRITEs that break the rules COB · seqrules.cob
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SEQRULES.
      * The rules of sequential access to an indexed file: WRITEs in
      * ascending key order, and a REWRITE only after a READ of the
      * same key. The file is listed at the end.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-FILE ASSIGN TO "ACCTS"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS SEQUENTIAL
               RECORD KEY IS AC-NUMBER
               FILE STATUS IS AC-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-FILE.
       01  ACCT-REC.
           05  AC-NUMBER        PIC X(6).
           05  AC-NAME          PIC X(16).
       WORKING-STORAGE SECTION.
       01  AC-STATUS            PIC XX.
       PROCEDURE DIVISION.
           OPEN OUTPUT ACCT-FILE
           MOVE "AC0003RAVI KUMAR" TO ACCT-REC
           WRITE ACCT-REC
           DISPLAY "WRITE AC0003              " AC-STATUS
           MOVE "AC0001ANITA DESHMUKH" TO ACCT-REC
           WRITE ACCT-REC
           DISPLAY "WRITE AC0001              " AC-STATUS
           MOVE "AC0005SUNITA RAO" TO ACCT-REC
           WRITE ACCT-REC
           DISPLAY "WRITE AC0005              " AC-STATUS
           CLOSE ACCT-FILE
           OPEN I-O ACCT-FILE
           MOVE "AC0003RAVI KUMAR" TO ACCT-REC
           REWRITE ACCT-REC
           DISPLAY "REWRITE, no READ first    " AC-STATUS
           READ ACCT-FILE
           DISPLAY "READ                      " AC-STATUS "  " AC-NUMBER
           MOVE "AC0004" TO AC-NUMBER
           REWRITE ACCT-REC
           DISPLAY "REWRITE, key now AC0004   " AC-STATUS
           CLOSE ACCT-FILE
           OPEN INPUT ACCT-FILE
           READ ACCT-FILE
           PERFORM UNTIL AC-STATUS NOT = "00"
               DISPLAY "in the file: " ACCT-REC
               READ ACCT-FILE
           END-PERFORM
           CLOSE ACCT-FILE
           STOP RUN.
Status 21 for a key out of order, 43 for a REWRITE with no READ, and a record that moved Python · seq_session.py
from session import files, run

# Sequential access: WRITEs out of key order, a REWRITE with no READ, and a REWRITE after the prime key was changed.
files("seqrules.cob")
run("""
cobc -x seqrules.cob
DD_ACCTS=seq.idx ./seqrules
""")

Output

$ cobc -x seqrules.cob
$ DD_ACCTS=seq.idx ./seqrules
WRITE AC0003              00
WRITE AC0001              21
WRITE AC0005              00
REWRITE, no READ first    43
READ                      00  AC0003
REWRITE, key now AC0004   00
in the file: AC0004RAVI KUMAR
in the file: AC0005SUNITA RAO

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 seq_session.py

AC0001 came after AC0003, so its WRITE returned 21, which IBM’s table explains as “the ascending requirements for successive record key values were violated”, and AC0001 was not stored. The REWRITE before any READ returned 43: in sequential access the statement before a REWRITE or DELETE must be a successful READ, because there is no other way to say which record to replace.

The last REWRITE is the trap. The program read AC0003, moved AC0004 into AC-NUMBER and ran REWRITE. IBM’s table gives status 21 for exactly this, when “the prime record key value was changed by the program” between a successful READ and the next REWRITE, and the record stays as it was. GnuCOBOL 3.2 returned 00, and the listing shows what it did: RAVI KUMAR is now AC0004, and AC0003 has gone from the file.

A key change that works here and fails on z/OS

Never change the prime key between a READ and its REWRITE. To give a record a new key, WRITE it under the new key, check for 00, then DELETE the old key and check again, so that both compilers do the same thing and a failure leaves the old record in place.

Checkpoint

Check: START and READ NEXT in key order · Sequential access, statuses 21 and 43

  1. Question 1 of 2 On the loaded file, a program moves AC0006 to AC-NUMBER, runs START ACCT-FILE KEY IS NOT LESS THAN AC-NUMBER, then READ NEXT. What does the READ NEXT return?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: AC0007 SUNITA RAO, with status 00

    START compares the key with every key in the file and sets the place at the first record that satisfies the comparison. Only when no record does is there an invalid key condition, status 23.

  2. Question 2 of 2 In sequential access, seqrules.cob read AC0003, moved AC0004 to AC-NUMBER and ran REWRITE. Which describes what IBM documents and what GnuCOBOL 3.2 did?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: IBM: status 21, a sequence error, and nothing changes. GnuCOBOL: status 00, and the record moved to key AC0004

    A REWRITE in sequential access replaces the record the last READ returned, so its key must not change. Enterprise COBOL refuses the change with 21; the GnuCOBOL 3.2 run moved the record to the new key without a word.

An alternate key reads the same records in another order

A branch wants the accounts of one city. The alternate key AC-CITY gives the same records a second order, by city, without a second copy of the file. bycity.cob reads by it twice: once at random, with READ … KEY IS AC-CITY, and once with a START on PUNE and READ NEXT until the city changes. nodups.cob is acctload.cob with WITH DUPLICATES taken out of the SELECT entry:

bycity.cob: a READ and a browse by the alternate key COB · bycity.cob
       IDENTIFICATION DIVISION.
       PROGRAM-ID. BYCITY.
      * Reads the accounts of one city through the alternate key
      * AC-CITY: a random READ, then a browse from START.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT ACCT-FILE ASSIGN TO "ACCTS"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS DYNAMIC
               RECORD KEY IS AC-NUMBER
               ALTERNATE RECORD KEY IS AC-CITY WITH DUPLICATES
               FILE STATUS IS AC-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  ACCT-FILE.
       01  ACCT-REC.
           05  AC-NUMBER        PIC X(6).
           05  AC-NAME          PIC X(16).
           05  AC-CITY          PIC X(10).
           05  AC-BALANCE       PIC 9(7)V99.
       WORKING-STORAGE SECTION.
       01  AC-STATUS            PIC XX.
       01  WANTED-CITY          PIC X(10).
       PROCEDURE DIVISION.
           OPEN INPUT ACCT-FILE
           MOVE "NAGPUR" TO AC-CITY
           READ ACCT-FILE KEY IS AC-CITY
           DISPLAY "READ KEY IS AC-CITY  " AC-STATUS "  " AC-NUMBER
               " " AC-CITY
           MOVE "PUNE" TO AC-CITY WANTED-CITY
           START ACCT-FILE KEY IS EQUAL TO AC-CITY
           DISPLAY "START AC-CITY = PUNE " AC-STATUS
           READ ACCT-FILE NEXT RECORD
           PERFORM UNTIL AC-STATUS NOT = "00" AND NOT = "02"
                   OR AC-CITY NOT = WANTED-CITY
               DISPLAY "READ NEXT            " AC-STATUS "  " AC-NUMBER
                   " " AC-CITY
               READ ACCT-FILE NEXT RECORD
           END-PERFORM
           DISPLAY "READ NEXT            " AC-STATUS "  the end"
           CLOSE ACCT-FILE
           STOP RUN.
The accounts of NAGPUR and PUNE, then a load where no two accounts may share a city Python · city_session.py
from session import files, run

# The accounts of one city through the alternate key, then the same load with no DUPLICATES on the city.
files("acctload.cob", "bycity.cob", "nodups.cob", "accounts.txt")
run("""
cobc -x acctload.cob && cobc -x bycity.cob && cobc -x nodups.cob
DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
DD_ACCTS=accounts.idx ./bycity
DD_ACCTIN=accounts.txt DD_ACCTS=nodups.idx ./nodups
""")

Output

$ cobc -x acctload.cob && cobc -x bycity.cob && cobc -x nodups.cob
$ DD_ACCTIN=accounts.txt DD_ACCTS=accounts.idx ./acctload > /dev/null
$ DD_ACCTS=accounts.idx ./bycity
READ KEY IS AC-CITY  00  AC0002 NAGPUR
START AC-CITY = PUNE 00
READ NEXT            00  AC0007 PUNE
READ NEXT            00  AC0005 PUNE
READ NEXT            00  AC0003 PUNE
READ NEXT            10  the end
$ DD_ACCTIN=accounts.txt DD_ACCTS=nodups.idx ./nodups
OPEN OUTPUT   00
WRITE AC0007  00
WRITE AC0002  00
WRITE AC0005  22  not written: the key is taken
WRITE AC0001  22  not written: the key is taken
WRITE AC0003  22  not written: the key is taken
WRITE AC0002  22  not written: the key is taken

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 city_session.py

The random READ for NAGPUR returned AC0002, not AC0001, because AC0002 was written first; IBM’s ALTERNATE RECORD KEY page says that “in random access, only the first record written in a series of records with duplicate keys can be retrieved”. The browse of PUNE read AC0007, AC0005 and AC0003, the order they were written in, and IBM’s READ page gives the same rule for sequential reading: such records “are made available in the order in which they were placed in the file”. The START changed the key of reference: The key whose order the next READ NEXT of an indexed file follows: the prime record key after OPEN, or the key that the last START named., so READ NEXT followed the city key instead of the account number.

Without WITH DUPLICATES the city must be unique, and the load stored only AC0007 and AC0002. AC0005 of PUNE and AC0001 of NAGPUR got 22, the status IBM gives for a duplicate alternate key without the DUPLICATES phrase, and so did AC0003 of PUNE; the second AC0002 got 22 for its prime key, as before.

What happened IBM’s Enterprise COBOL GnuCOBOL 3.2 in these runs
WRITE of a second PUNE account, WITH DUPLICATES 02 00
READ NEXT when the next record has the same city 02 00
WRITE of a second PUNE account, no DUPLICATES 22 22

Status 02 means “successful completion” with a duplicate key seen, and the handler of this GnuCOBOL build never set it. A program that treats 02 as an error fails on z/OS, and one that keeps reading while the status is 02 reads only one account per city here, so test for 00 or 02 as success and compare AC-CITY yourself, as bycity.cob does.

The order within one city

Records that share an alternate key come in the order they were written, never in prime-key order. When a report needs account order inside each city, sort the records, or make the account number part of the key.

On z/OS an indexed file is a VSAM key-sequenced data set

On z/OS the same SELECT entry opens a VSAM: Virtual Storage Access Method, the z/OS access method for key-sequenced, entry-sequenced, relative-record and linear data sets. COBOL's indexed and relative files are VSAM data sets on z/OS. data set. IBM’s Programming Guide pairs each COBOL organization with a VSAM one, and an indexed file is a KSDS: A key-sequenced data set: a VSAM data set whose records are stored and found by a key field. A COBOL indexed file on z/OS is a KSDS.. Its definition comes before any program runs: “You must predefine and catalog all VSAM data sets through the access method services DEFINE command.” The command is DEFINE CLUSTER, run by IDCAMS: Access method services, the z/OS utility that a job step runs as PGM=IDCAMS. Its commands define, load, print and delete VSAM data sets, such as DEFINE CLUSTER, REPRO and PRINT. More in “Relative files, VSAM organisations and IDCAMS”; INDEXED, its default organization, makes a KSDS, and KEYS gives the key’s length and its offset from byte 0, KEYS(6 0) for AC-NUMBER in the first six bytes. Step through what the account file needs:

Interactive · step by step The account file on z/OS, a KSDS with an alternate index Step through what each part of the SELECT entry needs on z/OS before the program can open the file.
The account file on z/OS, a KSDS with an alternate index, step 6 of 6. Showing SELECT ACCT-FILE, DD statement ACCTS, Base cluster (INDEXED, KEYS(6 0)), ALTERNATE RECORD KEY, The path, Alternate index.the ddnameread throughBLDINDEX reads itSELECT ACCT-FILEASSIGN TO ACCTSDD statement ACCTSnames the base clusterBase clusterINDEXED, KEYS(6 0)ALTERNATE RECORD KEYAC-CITY WITH DUPLICATESThe pathits own DD statementAlternate indexcity to account number

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The ddname. ASSIGN TO ACCTS names a ddname, so the DD statement of the job step decides which data set the program opens, as for a sequential file.
  2. A key-sequenced data set. The data set is a VSAM key-sequenced data set, defined in advance with the IDCAMS command DEFINE CLUSTER. INDEXED is its default organization, and KEYS gives the key's length and offset.
  3. The alternate key needs an index. The city key needs a second VSAM data set, an alternate index, defined with DEFINE ALTERNATEINDEX. Its key must match the program's ALTERNATE RECORD KEY.
  4. Built from the records. BLDINDEX reads every record of the base cluster and builds the alternate index from them, so the index starts out matching the data.
  5. The path. DEFINE PATH relates the alternate index to the base cluster. The program reads the records by city through the path, which has a DD statement of its own.
  6. The same program. Nothing in the COBOL changes. The SELECT entry and the statements are the ones acctbrowse.cob and bycity.cob ran here; only the data sets behind the names differ.

The city key is a data set of its own, an alternate index: A VSAM data set that holds the values of an alternate key with the prime keys of the records that carry them, so that a KSDS can be read in the order of that key through a path.. IBM lists three commands: DEFINE ALTERNATEINDEX, DEFINE PATH, which “allows you to access the records of the base cluster through the alternate keys”, and BLDINDEX, which reads every record of the base cluster to build the index. “The ALTERNATE RECORD KEY definitions must match the definitions in the catalog entry.” Each path gets a DD statement of its own: in IBM’s example the base cluster’s is MAINA and the two paths’ are MAINA1 and MAINA2.

What differs GnuCOBOL 3.2 in these runs Enterprise COBOL on z/OS
The records accounts.idx, a Berkeley DB file a KSDS, defined with DEFINE CLUSTER
The city key accounts.idx.1, made by the WRITEs an alternate index, built by BLDINDEX and read through a path
Choosing the file DD_ACCTS=accounts.idx before the run the DD statement ACCTS of the job step
More detail after an error the two-character FILE STATUS a second status item from VSAM as well

That second item is named after the first, FILE STATUS IS AC-STATUS VSAM-CODE: IBM describes it as “a 6-byte alphanumeric group data item that has three subordinate 2-byte binary fields”, a return code, a function code and a feedback code, and “the VSAM status code contains meaningful values when the COBOL file status key is not 0”.

Checkpoint

Check: Alternate keys, duplicates and status 02 · The indexed file on z/OS as a KSDS

  1. Question 1 of 2 A program moves PUNE to AC-CITY and runs READ ACCT-FILE KEY IS AC-CITY in random access. Which account does it return?

    Choose one answer.

    A hint

    Three accounts are in PUNE. Look at the order the lines arrived in.

    Show the answer: Question 1 of 2

    Answer: AC0007, the first PUNE account written to the file

    Duplicate alternate keys keep the order in which their records were written. A random READ by that key gets the first; START and READ NEXT read on to the others.

  2. Question 2 of 2 The account record is 41 bytes, with AC-NUMBER PIC X(6) in bytes 1 to 6. Which DEFINE CLUSTER keywords describe its key?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: INDEXED and KEYS(6 0)

    A COBOL indexed file is a KSDS on z/OS. IBM's DEFINE CLUSTER reference gives INDEXED as the default organization and KEYS as the key's length and its position from byte 0 of the record.

Practise: keys, statuses and access modes

These questions come from the six runs above, and each answer can be found in what they printed:

Practice that adapts to you

Practise this lesson

12 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 12 Which key of an indexed file must hold a different value in every record?

    Choose one answer.

    Show the answer: Question 1 of 12

    Answer: The prime record key, named by RECORD KEY

    The prime record key names one record and only one. Alternate keys may allow duplicates, and then several records share a value.

  2. Question 2 of 12 After the load, the folder holds accounts.idx and accounts.idx.1. A colleague backs up only accounts.idx. What is wrong with that?

    Choose one answer.

    Show the answer: Question 2 of 12

    Answer: accounts.idx.1 holds the city key, so a copy without it is not the whole indexed file

    An indexed file with an alternate key was two files on disk in this GnuCOBOL build, accounts.idx and accounts.idx.1, and the file is only whole when both are copied together.

  3. Question 3 of 12 A random READ asks for an account that is not in the file. Which status does it leave?

    Choose one answer.

    Show the answer: Question 3 of 12

    Answer: 23

    Missing record, status 23; taken key, status 22. Both are invalid key conditions, so the INVALID KEY phrase runs for either.

  4. Question 4 of 12 acctmaint.cob deleted AC0001 in random access, with no READ before the DELETE, and then read AC0001 by key. Why did that READ return 23?

    Choose one answer.

    Show the answer: Question 4 of 12

    Answer: The DELETE removed the record whose key was in AC-NUMBER, so AC0001 is now a missing record

    In random access DELETE removes the record whose key is in the key field, with no READ needed first. A READ of that key afterwards is a read of a missing record, status 23.

  5. Question 5 of 12 What does START ACCT-FILE KEY IS EQUAL TO AC-NUMBER do when no record has that key?

    Choose one answer.

    Show the answer: Question 5 of 12

    Answer: It sets status 23, the invalid key condition, and leaves no place to read on from

    START compares and positions; READ NEXT reads. A START that finds no record satisfying its comparison reports 23, so a browse must test the status of the START before its first READ NEXT.

  6. Question 6 of 12 The lines of accounts.txt came in the order AC0007, AC0002, AC0005, AC0001, AC0003. In which order did the browse from LOW-VALUES read them?

    Choose one answer.

    Show the answer: Question 6 of 12

    Answer: AC0001, AC0002, AC0003, AC0005, AC0007

    Sequential reading of an indexed file is in the ascending order of the key of reference. With the prime key that is account order, and with the city key it is city order.

  7. Question 7 of 12 In sequential access, a program runs REWRITE without a READ before it. Which status does it get?

    Choose one answer.

    Show the answer: Question 7 of 12

    Answer: 43

    Sequential access replaces only the record it last read. With no READ there is nothing to replace, a logic error, status 43.

  8. Question 8 of 12 A nightly job sorts the accounts by number, then loads them into a new indexed file opened OUTPUT in sequential access. One night the sort step is skipped. What does the load do with accounts.txt as it is?

    Choose one answer.

    Show the answer: Question 8 of 12

    Answer: It writes AC0007 and gets 21 for every later account, since each key is below the highest one written

    Sequential access to an indexed file is a promise that keys come in ascending order. A load that breaks the promise loses every record whose key is below the highest key written so far.

  9. Question 9 of 12 bycity.cob started on PUNE and read on. In which order did the three PUNE accounts come, and why?

    Choose one answer.

    Show the answer: Question 9 of 12

    Answer: AC0007, AC0005, AC0003, the order in which they were written

    Within one value of an alternate key, records come in the order they were written. A program that needs them in account order within each city must sort them or add the account to the key.

  10. Question 10 of 12 A program reads accounts by city and keeps reading while the status is 02, as IBM documents for a duplicate that follows. Moved to this GnuCOBOL build, what does it do?

    Choose one answer.

    Show the answer: Question 10 of 12

    Answer: It reads only the first account of each city, because the handler returned 00, never 02

    Status 02 is successful completion with a duplicate noticed, and not every runtime reports it. Treat 00 and 02 alike as success, and compare the key yourself to find where one city ends.

  11. Question 11 of 12 On z/OS, what must exist besides the base cluster before a program can read a KSDS by an alternate key?

    Choose one answer.

    Show the answer: Question 11 of 12

    Answer: An alternate index, built from the base cluster, and a path that relates it to the cluster

    A KSDS has one prime key. Each alternate key is a separate VSAM data set, the alternate index, reached through a path whose DD statement the job step provides.

  12. Question 12 of 12 A KSDS OPEN fails on z/OS with file status 90. Where does the program find more detail, as IBM describes it?

    Choose one answer.

    Show the answer: Question 12 of 12

    Answer: In the second item of the FILE STATUS clause, 6 bytes holding three 2-byte binary codes from VSAM

    FILE STATUS IS FS-CODE VSAM-CODE gives two items: the two-character status every COBOL file has, and, for VSAM files, six bytes of return, function and feedback codes for the case the status cannot describe.

An account maintenance run that checks every status

Where GnuCOBOL is installed, write a program that reads a file of transactions, A to add an account, C to change its city, X to close it and L to list a city, and applies each to the indexed file with a check of every status: 22 for an add of a taken key, 23 for a change or close of a missing one, and anything other than 00, 02 or 10 as an error that ends the run with return code 12. Test it with an add of AC0003, a change of AC0004, a close of AC0007 and a list of PUNE, and compare the file with accounts.txt afterwards.

Interview questions

Warm-up (fresher to 2–5 years): how do random, sequential and dynamic access to an indexed file differ?

Random access reads, writes, rewrites and deletes one record by the key placed in the key field, in any order. Sequential access reads the records in ascending key order, writes only in ascending key order, a WRITE out of order gets status 21, and rewrites or deletes only the record just read, or gets 43. Dynamic access allows both in one run: READ by key, and START followed by READ NEXT to read on in key order. A maintenance program that applies transactions in any order uses random access, a report over the whole file uses sequential access, and a program that finds a starting point and reads on from it, such as all the accounts of one city, uses dynamic access.

Warm-up (fresher to 2–5 years): what do file statuses 22 and 23 mean on an indexed file?

Both are invalid key conditions, so an INVALID KEY phrase runs for either. 22 means a WRITE or REWRITE would create a duplicate prime key, or a duplicate alternate key that was declared without DUPLICATES, and nothing was stored, as for the second AC0002 in this lesson. 23 means a random READ, REWRITE, DELETE or a START found no record with the key, as for READ AC0004 and START KEY IS EQUAL TO AC0006. A program checks for both after every keyed statement, because each needs a different answer: 22 is often a duplicate input record, and 23 a transaction for an account that does not exist.

Two harder questions start from programs that went wrong:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to mid

    After a change to an address-update program, some accounts lost their names and balances: the fields came back as spaces and zeros, yet every REWRITE returned status 00. The file is indexed and opened I-O in random access. What went wrong, and how do you fix and test it?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    A program lists the accounts of each branch through an alternate key declared WITH DUPLICATES. It finds the first account with START and READ NEXT, then keeps reading while the file status is 02. On z/OS it lists every account; after a move to GnuCOBOL it lists one per branch. Explain, and rewrite the loop.

    Model answer, Pro. First step and follow-ups

Organisations named on this page

The keyed-file rules on this page, from START to the VSAM status item, are quoted from IBM’s Enterprise COBOL and z/OS manuals. IBM and the GnuCOBOL project have no part in MySmartCoPilot, and the files shown were written by GnuCOBOL 3.2 with its Berkeley DB handler.

Flashcards · 8 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. What do RECORD KEY and ALTERNATE RECORD KEY declare?

    RECORD KEY names the prime key of an indexed file, whose values must be unique. ALTERNATE RECORD KEY names a second key, and WITH DUPLICATES lets several records share its value.

  2. What do file statuses 22 and 23 mean on an indexed file?

    Both are invalid key conditions. 22: a WRITE or REWRITE would duplicate a prime key, or an alternate key without DUPLICATES, and nothing is stored. 23: a random READ, REWRITE, DELETE or START found no record with the key.

  3. How can a REWRITE in random access blank a record's fields and still return 00?

    It writes the whole record area under the key it holds, with no READ required. After INITIALIZE and a MOVE of the key and one field, every other field became spaces or zeros. READ first, change, then REWRITE.

  4. What does START do on an indexed file?

    It sets a place in key order and reads nothing; READ NEXT then reads on until status 10. KEY IS NOT LESS THAN a missing key lands on the next one, while KEY IS EQUAL TO a missing key returns 23.

  5. What are the three access modes of an indexed file?

    SEQUENTIAL, the default, works in key order. RANDOM reads and writes one record by its key. DYNAMIC does both in one run: READ by key, and START with READ NEXT.

  6. What do statuses 21 and 43 mean in sequential access?

    21: keys written out of ascending order, or, on z/OS, a prime key changed between a READ and its REWRITE. 43: a REWRITE or DELETE without a successful READ before it.

  7. In what order do records that share an alternate key come back?

    In the order they were written, never in prime-key order. A random READ by that key returns only the first of them.

  8. What does an indexed file become on z/OS?

    A VSAM key-sequenced data set, a KSDS, defined beforehand with IDCAMS DEFINE CLUSTER, whose KEYS give the key's length and offset. Each alternate key needs an alternate index, built by BLDINDEX and read through a path with its own DD statement.

Key takeaways

  • An indexed file keeps its records in the order of a unique prime record key; a WRITE of a key that is taken stores nothing and returns 22, and GnuCOBOL kept the alternate key in a second file, accounts.idx.1.
  • Random access reads, rewrites and deletes the record whose key is in the key field and returns 23 when there is none; a REWRITE writes the whole record area, so read the record before changing one field.
  • START sets a place in key order without reading, and READ NEXT reads on from it until status 10; a START that no key satisfies returns 23.
  • Sequential access writes keys in ascending order, or gets 21, and rewrites only the record just read, or gets 43; a changed prime key before the REWRITE is 21 on z/OS, while GnuCOBOL 3.2 moved the record.
  • Records with the same alternate key come in the order they were written; IBM reports such duplicates with status 02, which this GnuCOBOL build returned as 00.
  • On z/OS an indexed file is a VSAM KSDS defined with IDCAMS DEFINE CLUSTER, and each alternate key needs an alternate index and a path with its own DD statement.

Terms in this lesson

alternate index
A VSAM data set that holds the values of an alternate key with the prime keys of the records that carry them, so that a KSDS can be read in the order of that key through a path.
alternate record key
A second key of an indexed file, named by ALTERNATE RECORD KEY, by which the same records can also be read and browsed. WITH DUPLICATES lets several records share one value.
dynamic access
ACCESS MODE IS DYNAMIC: in the same run, a program may read an indexed or relative file by key and also read on through it in order with START and READ NEXT.
indexed file
A file whose records are kept in the order of a key, so a program can read one record by its key or read them all in key order. ORGANIZATION IS INDEXED; on z/OS it is a VSAM key-sequenced data set.
invalid key condition
What a keyed WRITE, READ, REWRITE, DELETE or START reports when it cannot place or find a record: a status starting with 2, such as 22 for a taken key or 23 for a missing one. The INVALID KEY phrase runs then.
key of reference
The key whose order the next READ NEXT of an indexed file follows: the prime record key after OPEN, or the key that the last START named.
KSDS
A key-sequenced data set: a VSAM data set whose records are stored and found by a key field. A COBOL indexed file on z/OS is a KSDS.
prime record key
The key that RECORD KEY names in an indexed file. Its values must be unique, they set the order of the records, and a random READ, REWRITE or DELETE finds its record by it.
VSAM
Virtual Storage Access Method, the z/OS access method for key-sequenced, entry-sequenced, relative-record and linear data sets. COBOL's indexed and relative files are VSAM data sets on z/OS.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.