The COBOL WRITE statement adds a new record to a file. For sequential files you write the next record (at the end of the file); for indexed or relative files you set the key in the record area and WRITE adds a record with that key. The file must be open in OUTPUT, EXTEND, or (for indexed/relative) I-O. You can use WRITE record-name FROM identifier to write from a working-storage area, and for sequential print files you can use BEFORE or AFTER ADVANCING to control line and page spacing. This page explains WRITE for sequential, indexed, and relative files, INVALID KEY, and report-writing clauses.
WRITE is like adding a new card to a stack or a new folder to a filing cabinet. You must have the file open for writing (like having permission to add). For a stack, you add at the end—that is sequential WRITE. For a filing cabinet where every folder has a number, you put the number on your new folder and add it; if that number is already used, the system says "invalid key" (duplicate). WRITE is only for adding new things; to change something that is already there you have to read it first and then REWRITE it.
WRITE adds one logical record to the file. The record comes from the file's record area (defined under the FD). You can optionally use FROM identifier so that the data is moved from identifier to the record area and then written—equivalent to MOVE identifier TO record-name followed by WRITE record-name. The file must be open in OUTPUT (new file or overwrite), EXTEND (add to end of existing sequential file), or I-O (for indexed/relative when adding new records). After a successful WRITE, the record is part of the file. For sequential files, the next WRITE adds after it. For indexed files, the record is placed according to its key; for relative files, at the relative record number you set.
| Form | Typical use |
|---|---|
| Sequential WRITE | Add next record; file open OUTPUT or EXTEND. Optional FROM, BEFORE/AFTER ADVANCING for print. |
| Indexed WRITE | Add record with key in record area. OPEN OUTPUT or I-O. INVALID KEY for duplicate or error. |
| Relative WRITE | Add record at relative position. Key (relative record number) in RELATIVE KEY. INVALID KEY if position invalid. |
For a sequential file (or line-sequential/report file), WRITE adds the next record at the end of the file. Open the file with OUTPUT (to create or overwrite) or EXTEND (to add to an existing file). The record you write is the one defined under the FD. You can write FROM a working-storage area so the record is built there and then written. For print files (e.g. report output), you can use BEFORE ADVANCING or AFTER ADVANCING to control how many lines or pages are advanced before or after the write; this controls spacing and page breaks.
12345678OPEN OUTPUT REPORT-FILE. MOVE 'Page 1' TO REPORT-LINE. WRITE REPORT-REC FROM REPORT-LINE BEFORE ADVANCING PAGE. *> Write body lines, one line each WRITE REPORT-REC FROM WS-DETAIL-LINE AFTER ADVANCING 1 LINE. CLOSE REPORT-FILE.
WRITE record-name FROM identifier-1 moves the data from identifier-1 to the record area of record-name and then writes that record. The record description (record-name) must be the one associated with the file. The move follows normal COBOL move rules (e.g. alphanumeric to alphanumeric, numeric to numeric). Using FROM lets you build the record in working storage and write it in one statement without explicitly moving to the record area first. If the record area is larger than identifier-1, the rest may be padding or undefined; if smaller, the move may truncate. Ensure the layout and length are correct.
For sequential files used for printing (e.g. report files, line-sequential with a printer or SYSOUT), you can control vertical positioning with ADVANCING. BEFORE ADVANCING means: write the record first, then advance. AFTER ADVANCING means: advance first, then write. You specify LINE or LINES (e.g. AFTER ADVANCING 2 LINES) or PAGE. PAGE causes a form feed or repositioning to the next page; with a LINAGE clause in the FD, positioning is to the first line of the next page. Use BEFORE ADVANCING PAGE to write a page header and then go to the next page; use AFTER ADVANCING PAGE to go to a new page and then write. If you omit ADVANCING, behavior is implementation-dependent (often one line).
| Clause | Meaning |
|---|---|
| BEFORE ADVANCING 1 LINE | Write the record, then advance one line. Default for many print files. |
| AFTER ADVANCING 1 LINE | Advance one line, then write the record. Puts a blank line before the record. |
| BEFORE ADVANCING PAGE | Write the record (e.g. page header), then advance to the next page (form feed). |
| AFTER ADVANCING PAGE | Advance to next page, then write. Often used after finishing a page. |
| ADVANCING integer LINES | Advance that many lines before or after writing. Useful for spacing. |
For an indexed file (e.g. VSAM KSDS), you add a new record by setting the prime record key (and any alternate keys that are part of the record) in the record area and issuing WRITE record-name. The file can be open in OUTPUT (new file) or I-O (existing file; you use WRITE to add and REWRITE to update). The key value must be unique unless the file allows duplicates for that key. If the key is a duplicate or otherwise invalid, CICS sets file status (e.g. 22 for duplicate key) and executes the INVALID KEY clause if you coded it. NOT INVALID KEY is executed when the write succeeds. Always check FILE STATUS or use INVALID KEY so you do not assume the write succeeded.
12345678910111213*> Key is part of record MOVE WS-NEW-ID TO CUST-ID MOVE WS-NEW-NAME TO CUST-NAME MOVE WS-NEW-AMT TO CUST-AMT WRITE CUST-REC FROM WS-CUST-REC INVALID KEY DISPLAY 'Duplicate or invalid key: ' CUST-ID NOT INVALID KEY ADD 1 TO WS-ADD-COUNT END-WRITE. IF WS-FILE-STATUS = '00' PERFORM RECORD-ADDED END-IF.
For a relative file, you set the relative record number in the RELATIVE KEY data item (defined in the SELECT) and then WRITE the record. The record is written at that relative position. If the position is invalid (e.g. out of range or already used, depending on implementation) or the write fails, INVALID KEY is taken and file status is set. Use NOT INVALID KEY for success path. The file is typically open in OUTPUT or I-O.
For indexed and relative files, INVALID KEY is the clause that runs when the write cannot be completed because of a key condition. Common causes are: duplicate key (status 22), invalid relative record number, or other key-related error. In the INVALID KEY phrase you handle the error (e.g. display a message, set a flag, or try another key). NOT INVALID KEY runs when the write succeeds. You can use one or both. File status is always set: 00 for success, 22 for duplicate key (indexed), and other values for other errors. Checking FILE STATUS after every WRITE is good practice so you do not miss errors if you omit INVALID KEY.
WRITE adds a new record. REWRITE replaces an existing record. You use REWRITE only after you have read that record (with READ). The record you REWRITE must be the one you just read; the key must not change (for indexed files). So: to add a record, use WRITE; to change a record that is already in the file, use READ (with the key or position), modify the data in the record area, then REWRITE. Do not use WRITE to "update"—that would try to add a second record and can cause duplicate key or wrong data.
After each WRITE, the file's FILE STATUS (if defined) is updated. Typical values: 00 success; 22 duplicate key (indexed); 24 relative key out of range or other key error; 30 permanent error (e.g. I/O error); 34 boundary or file full. Always check the status so you can handle duplicates and errors. For sequential files, status 00 is success; other values indicate I/O or device errors.
1. WRITE is used to:
2. INVALID KEY on WRITE for an indexed file usually means:
3. WRITE record-name FROM ws-area does: