RPGLE CHAIN Opcode Reference

chain reads one record from a file by key. This page covers the syntax, the forms of the search argument, how to test the result, what happens to record locks and file position, and how chain differs from setll.

It is a focused page. The other file operations are in the RPGLE File I/O Opcodes Reference, and the functions that report the outcome are in the RPGLE File and Error BIFs Reference.

The examples are free-form RPGLE. They use a keyed file with the key fields CUSTKEY and ORDNO, declared like this:

dcl-f ordWork keyed usage(*update) extfile('*LIBL/ORDERW') rename(ORDERW : ordRec);

dcl-s keyVal char(5);
dcl-s keyCust char(5);
dcl-s keyOrd packed(5 : 0);

Syntax

chain{(ENHMR)} search-arg name {data-structure};
PartMeaning
search-argThe key, or the relative record number, of the record to read
nameThe file name, or for an externally described file the record format name
data-structureOptional. Reads the record into this data structure instead of the file’s own fields
(E)Errors are not fatal. Test %error afterwards
(N)Read without locking the record. For an update file only
(H), (M), (R)Rounding and precision, allowed only when the search argument is a list or %kds

chain reads the first record whose key matches the search argument. If no record matches, that is the “not found” outcome, not an error.

Single key

A single key can be a field, a named constant, a figurative constant or a literal.

keyVal = 'C0001';
chain keyVal ordWork;
if %found(ordWork);
  // ORDNO and the other fields now hold the record
endif;

When %found is on, the record is in the file’s fields. When it is off, no record has that key and the fields keep the values they had.

Composite key

For an externally described file, a composite key can be a list of values in parentheses, a KLIST name (older code), or %kds with a key data structure.

keyCust = 'C0001';
keyOrd = 2;
chain (keyCust : keyOrd) ordWork;

The values go in key order, and each must match the type of its key field. Expressions are allowed in the list, for example chain (%upper(name) : code + 1) fileRec;.

%kds takes the values from the top-level subfields of a data structure, and an optional second argument says how many of them to use.

dcl-ds keyDs likerec(ordRec : *key);

keyDs.CUSTKEY = 'C0001';
keyDs.ORDNO = 2;
chain %kds(keyDs) ordWork;

chain %kds(keyDs : 1) ordWork;       // partial key: only CUSTKEY is used

A partial key matches the first record whose leading key fields are equal. In the second chain above, that is the first record for customer C0001, whatever its ORDNO.

Read into a data structure

Name a data structure after the file to read the record into it. For an externally described file, define the structure with likerec or extname.

dcl-ds ordData likerec(ordRec : *input);

keyVal = 'C0001';
chain keyVal ordWork ordData;
if %found(ordWork);
  // ordData.ORDSTS holds the status of the record that was read
endif;

Testing the result

Use %found after chain.

TestMeaning after chain
%found(file) is *onA record with that key was read
%found(file) is *offNo record has that key
%eof(file)Not set by chain. Do not test it here
%error*on after a chain(e) that failed for a reason other than not found

Older code puts the NR indicator in positions 71 to 72, which is on when no record is found, so it is the opposite of %found. The Fixed-Format to Free-Format Opcode Mapping shows how to convert that form. Positions 75 and 76 must be blank.

To handle real file errors, code the (E) extender or an ER indicator, but not both.

keyVal = 'C0001';
chain(e) keyVal ordWork;
if %error;
  // the read failed: handle it
elseif %found(ordWork);
  // process the record
endif;

Locks and the (N) extender

On a file declared for update, chain locks the record it reads, unless you code (n). On an input-only file, records are read without locks and no extender is allowed.

keyVal = 'C0001';
chain(n) keyVal ordWork;           // read without locking

Use (n) when you only want to look at the record. A lock keeps other jobs from updating that record until you release it, so do not hold one while waiting for a user.

CHAIN then UPDATE

After a successful chain, an update on the same file changes the record that was just 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 before update. Test %found first, because an update after a failed chain has no record to change. The RPGLE UPDATE, WRITE and DELETE Opcode Reference covers which reads allow an update.

File position after CHAIN

After a successful chain, the file is positioned at that record, so a read returns the record that follows it. After a chain that fails, because nothing was found or an error occurred, the file position cannot be relied on. Reposition it with chain or setll before the next read.

CHAIN versus SETLL

chainsetll
Reads a recordYesNo
Result test%found%found and %equal
If the exact key is missingNot found. Nothing is readPositions at the next higher key
Typical useOne record by keyStart of a range, followed by read or reade

Use chain to get one record. Use setll when you want to start reading at a key, or when you only need to know whether a key exists and do not need the data. The RPGLE SETLL and SETGT Opcode Reference covers positioning.

Common mistakes

  • Using the record fields without testing %found.
  • Testing %eof after chain.
  • Calling read straight after a chain that found nothing.
  • Giving the key values in the wrong order or with the wrong type.
  • Holding a lock by reading an update file with chain when chain(n) would do.
  • Changing a key field and then calling update.

FAQ

What does CHAIN return when the key is not found?

Nothing is read. %found is off, and in older code the NR indicator is on.

Can CHAIN use a partial key?

Yes, with a list that has fewer values than the key, or with %kds(ds : n). It returns the first record whose leading key fields match.

Do I need an indicator?

No. In free-form code, test %found(file) and use the (e) extender with %error for file errors.

Summary

  • chain search-arg file; reads the first record whose key matches, and %found says whether it did.
  • Give a composite key as a list of values or with %kds, in key order, and use %kds(ds : n) for a partial key.
  • On an update file, (n) reads without a lock, and update after a successful chain changes that record.
  • After a failed chain, reposition the file before reading. For a range of records, use setll with read or reade, described in the RPGLE File I/O Opcodes Reference.

Leave a Comment

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

Scroll to Top