The COBOL READ statement retrieves one record from a file and places it in the file's record area. You use READ for sequential files to get the next record, and for indexed or relative files to get either the next record (READ NEXT) or a specific record by key (READ with KEY). After each READ, the file status is set so you can detect success, end of file, or errors. This page explains the different forms of READ, when to use AT END and INVALID KEY, and how READ fits with OPEN mode and file organization.
READ is like taking the next card from a stack (or the card with a certain number). You must have opened the file first (like opening the drawer). For a stack in order, you always take the next one—that is sequential READ. For a box of cards sorted by number, you can either ask for "the next one" or "the one with this number"—that is READ NEXT or READ by key. When there are no more cards, the system tells you "end of file" (AT END or status 10). When you ask for a number that is not there, you get "invalid key" (INVALID KEY or status 23). Your program checks that and decides what to do.
READ retrieves one logical record from the file and makes it available in the record area defined under the FD for that file. The file must be open in INPUT or I-O mode. After a successful READ, the record content is in the record description; your program can then process it, update it (and REWRITE for I-O), or use key fields for further access. For sequential organization, each READ returns the next record in physical order. For indexed organization, READ can be by key (random) or NEXT (sequential in key order). For relative organization, READ can be by relative record number or NEXT. The exact syntax and clauses depend on the file organization and access mode.
| Form | Typical use |
|---|---|
| Sequential READ | Next record; sequential and indexed/relative |
| READ with KEY | Specific record by key; indexed or relative |
| READ NEXT | Next in sequence; explicit on dynamic access |
For a sequential file, or for an indexed/relative file in sequential access mode, READ gets the next record. No key is specified. The usual pattern is: OPEN INPUT file, then in a loop READ file AT END set a flag or EXIT or PERFORM end-of-file logic, and when not at end process the record. Example: READ CUST-FILE AT END SET WS-EOF TO TRUE END-READ. When AT END is taken, no record was read; the record area may be unchanged. You should also check FILE STATUS: 00 for success, 10 for end of file. Status 10 and AT END both indicate end of file; use one or both consistently.
12345678910OPEN INPUT CUST-FILE. PERFORM UNTIL WS-EOF READ CUST-FILE AT END SET WS-EOF TO TRUE END-READ IF NOT WS-EOF PERFORM PROCESS-RECORD END-IF END-PERFORM CLOSE CUST-FILE.
For indexed or relative files opened with ACCESS MODE RANDOM or DYNAMIC, you can read a specific record by key. You move the key value to the key field in the record area (or the key data item), then issue READ file RECORD KEY IS key-name (or KEY IS data-name). If a record with that key exists, it is read and status is 00. If not, INVALID KEY is taken and status is typically 23 (record not found). You must define the key in the FD (RECORD KEY for indexed, RELATIVE KEY for relative) and set it before the READ. For indexed files with multiple keys, you specify which key you are using. For relative files, the key is the relative record number.
12345678*> Indexed file: key in record MOVE WS-SEEK-KEY TO CUST-ID READ CUST-FILE RECORD KEY IS CUST-ID INVALID KEY DISPLAY 'Not found ' CUST-ID END-READ IF WS-FILE-STATUS = '00' PERFORM PROCESS-RECORD END-IF
For indexed or relative files with ACCESS MODE DYNAMIC, you can mix keyed reads and sequential reads. READ NEXT (or READ ... NEXT RECORD) gets the next record in key sequence (indexed) or relative position (relative). It is used after you have positioned the file (e.g. with a keyed READ or START) and want to read forward. READ NEXT also sets AT END when there is no next record. So the same AT END and FILE STATUS checks apply as for sequential READ.
AT END is an optional clause on the READ. It is executed when the READ could not return a record because the end of the file has been reached (no next record). When AT END is taken, the record area is not updated with new data; your program should not process a "new" record in that iteration. Typical use: SET ws-eof TO TRUE, or PERFORM end-of-file paragraph, or EXIT PERFORM. File status 10 is also set when at end. For keyed READ, end of file is not INVALID KEY; INVALID KEY means "no record for this key." End of file for sequential/READ NEXT is AT END and status 10.
INVALID KEY is used with READ (or WRITE, REWRITE, DELETE, START) when the file has a key (indexed or relative). For READ with KEY, INVALID KEY is taken when no record exists with the specified key value (record not found). File status 23 is typical. Your program might display an error, add a new record (WRITE), or continue with a default. Do not assume the record area contains valid data when INVALID KEY is taken. For WRITE, INVALID KEY might mean duplicate key (status 22) or other key violation; for DELETE, record not found. Always handle INVALID KEY when using keyed operations.
If you declare FILE STATUS in the SELECT, the system sets it after every READ. Common values: 00 = success, record read; 10 = end of file (no next record); 23 = record not found (keyed read); 21 = sequence error (sequential file read out of order); 30 = permanent error. Your program should check the status after each READ (or use AT END/INVALID KEY) and avoid processing the record area when status is not 00. Checking FILE STATUS in addition to AT END/INVALID KEY gives you a single place to handle all error codes and eases debugging.
1. After a sequential READ, file status 10 means:
2. To read a record by key from an indexed file you use:
3. AT END in a READ statement is executed when: