RPGLE File I/O Opcodes Reference

This page is a lookup for the RPGLE file operations: the opcodes that position a file, read records, and add, change or remove them. For each one it gives the free-form syntax, what it does, and how to test the outcome by name instead of with a result indicator.

It is not a lesson on files. To find an opcode outside file input and output, use the RPGLE Opcode Reference. To convert old fixed-format file code, use the Fixed-Format to Free-Format Opcode Mapping.

All examples are free-form RPGLE, and they use a keyed file with the key fields CUSTKEY and ORDNO.

File operations at a glance

In the syntax column, braces { } mark optional parts, and name is a file name or, for an externally described file, a record format name.

OpcodeFree-form syntaxWhat it does
chainchain{(ENHMR)} search-arg name {data-structure};Reads one record by key
setllsetll{(EHMR)} search-arg name;Positions the file at the first record with a key equal to or greater than the search argument
setgtsetgt{(EHMR)} search-arg name;Positions the file after the last record with a key equal to the search argument
readread{(EN)} name {data-structure};Reads the next record
readereade{(ENHMR)} search-arg or *key name {data-structure};Reads the next record if its key equals the search argument
readpreadp{(EN)} name {data-structure};Reads the previous record
readpereadpe{(ENHMR)} search-arg or *key name {data-structure};Reads the previous record if its key equals the search argument
writewrite{(E)} name {data-structure};Adds a new record
updateupdate{(E)} name {data-structure or %fields(name{:name...})};Changes the record that was last read
deletedelete{(EHMR)} {search-arg} name;Removes a record

How to test the result

Older code put a resulting indicator in columns 71 to 76 of a fixed-format line. In free-form you test a built-in function.

OpcodeResulting indicator (fixed format)Free-form test
chainNR (71-72): record not found%found(file), which is the opposite of NR
setllNR (71-72): search argument above the highest key; EQ (75-76): exact match%found(file) and %equal(file)
setgtNR (71-72)%found(file)
read, readeEOF (75-76)%eof(file)
readp, readpeBOF (75-76)%eof(file), which is on at the beginning of the file
deleteNR (71-72)%found(file)
write, updateER (73-74)%error after the (e) extender

The ER indicator and the (e) extender are alternatives, and you cannot specify both. Each function returns *on or *off. When you give it a file name it reports on that file, and without one it reports on the most recent file operation. The complete list of built-in functions is in the RPGLE Built-in Functions Reference.

CHAIN

chain reads the record whose key equals the search argument. It positions the file at that record, so a following read returns the record after it. If the key is not found, %found is off and the file must be repositioned before the next read. Key forms, locks and file position have their own page, the RPGLE CHAIN Opcode Reference.

keyVal = 'C0001';
chain keyVal ordWork;
if %found(ordWork);
  // the record is in the file buffer
endif;

The search argument can be one key, a list of values in parentheses, or %kds with a data structure, for a composite key. A partial key matches the first record whose leading key fields are equal. On an update file, chain locks the record unless you add the (n) extender.

SETLL and SETGT

setll and setgt position the file without reading a record. A read after them returns the record at that position.

setll positions at the first record whose key is equal to or greater than the search argument, and %equal is on only when the key matches exactly. setgt positions after the last record with the search argument key.

keyVal = 'C0001';
setll keyVal ordWork;
if %equal(ordWork);
  read ordWork;           // the first C0001 record
endif;

keyVal = 'C0001';
setgt keyVal ordWork;
read ordWork;             // the first record after every C0001 record

setll *start positions at the start of the file and setll *end at the end. *loval and *hival do the same in most files, but IBM lists cases where they do not, such as a descending key. Where the file is left and the existence test have their own page, the RPGLE SETLL and SETGT Opcode Reference.

READ

read returns the record at the current position and moves forward. Test %eof after each read, and read again at the end of the loop body.

setll *loval ordWork;
read ordWork;
dow not %eof(ordWork);
  records += 1;
  read ordWork;
enddo;

Do not test %eof before the first read. It reflects the last read, not the next one.

READE

reade reads the next record only if its key equals the search argument. At a different key, %eof comes on, so the loop ends when the key changes as well as at the end of the file.

records = 0;
keyVal = 'C0001';
setll keyVal ordWork;
reade keyVal ordWork;
dow not %eof(ordWork);
  records += 1;
  reade keyVal ordWork;
enddo;

Use setll first. Without it, reade starts from wherever the previous operation left the file. Loops, key changes and end of file are covered in the RPGLE READ, READE and READP Opcode Reference.

READP and READPE

readp and readpe work like read and reade but move backwards. At the beginning of the file, %eof comes on.

setll *hival ordWork;
readp ordWork;            // the last record in the file

UPDATE

update rewrites the record that was last read. It needs a file declared for update, and the record must have been read and locked by chain or read. Change the fields, then name the record format.

keyCust = 'C0001';
keyOrd = 2;
chain (keyCust : keyOrd) ordWork;
if %found(ordWork);
  ORDSTS = 'S';
  update ordRec;
endif;

Do not change a key field of the record you are updating. To restrict the update to some fields, name them in %fields.

WRITE

write adds a record built from the current field values. The file must be declared for output.

CUSTKEY = 'C0003';
ORDNO = 4;
ORDSTS = 'N';
write ordRec;

write takes a record format name for an externally described file. If the key already exists in a file that does not allow duplicate keys, the operation fails, so use the (e) extender and test %error when that can happen.

DELETE

delete removes a record. After a chain or read on an update file, name the record format to remove the record that was just read. You can also give a search argument and a file name to delete by key.

if %found(ordWork);
  delete ordRec;
endif;

With a search argument, %found is off when no record had that key. Usage keywords, %fields and status codes are in the RPGLE UPDATE, WRITE and DELETE Opcode Reference.

File declarations that these operations need

The usage keyword on the file declaration decides which operations are allowed.

UsageAllows
*inputchain, setll, setgt, read, reade, readp, readpe
*updateThe input operations and update
*update : *deleteThe above and delete
*outputwrite

A file declared for update locks each record that chain or read returns until you update, delete or read again. Declare the file for input only when you do not change it.

Common mistakes

  • Reading in a loop without testing %eof after every read.
  • Calling reade without setll, so the position is wrong.
  • Testing %found after a read. After a read, use %eof.
  • Calling update or delete before a successful chain or read.
  • Declaring the file for input and then trying to write or update.
  • Changing a key field before update.

FAQ

What is the difference between SETLL and CHAIN?

chain reads a record. setll only positions the file, and a later read returns the record. Use chain when you want one record by key, and setll with reade or read when you want a range.

How do I know a CHAIN found nothing?

%found is off. The old form is the NR indicator, which is on when the record is not found.

Do I need an indicator for end of file?

No. Test %eof(file) after each read instead of using the EOF indicator.

Summary

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top