RPGLE UPDATE, WRITE and DELETE Opcode Reference

update changes a record, write adds one and delete removes one. This page covers the syntax, the file declaration each needs, which record update and delete act on, the %fields form, what happens when write meets a duplicate key, and the file status codes you can test.

It is a focused page. The short entry for each file operation is in the RPGLE File I/O Opcodes Reference, reading one record and its lock is in the RPGLE CHAIN Opcode Reference, and the functions that report errors 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 and the field ORDSTS, which holds three records: C0001 / 1, C0001 / 2 and C0002 / 3, all with status N.

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

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

Syntax

update{(E)} name {data-structure | %fields(name{:name...})};
write{(E)} name {data-structure};
delete{(EHMR)} {search-arg} name;
OpcodeWhat it doesOperand notes
updateRewrites the last locked record that was readFor an externally described file, name is the record format of the record that was read
writeAdds a new record built from the current field valuesname is a record format, or a program-described file
deleteRemoves a recordWith no search argument it removes the current record. With a key it removes the record with that key

Each takes the (E) extender, and delete also takes H, M and R when the search argument is a list or %kds. The (E) extender and the ER indicator are alternatives, and you cannot code both.

The file declaration

The usage keyword on dcl-f decides which operations the file allows.

UsageAllows
*inputThe read and position operations only
*updateThe input operations and update
*deletedelete, and it must be named in a free-form declaration
*outputwrite

In free-form code, *update does not make a file delete-capable. Name *delete as well. To add records to a file that is also read or updated, name *output too, as the declaration above does. The older fixed-format entry U implied delete, so code converted from it needs *delete added.

UPDATE

update rewrites the last locked record that an input operation retrieved from the file. Change the fields, then name the record format.

keyDs.CUSTKEY = 'C0001';
keyDs.ORDNO = 2;
chain %kds(keyDs) ordWork;
if %found(ordWork);
  ORDSTS = 'S';
  update ordRec;
endif;

The current values of all the fields in the record format are written back, so a field you did not change is written with the value it had when you read it. Test %found first, because there is no record to change after a chain that found nothing.

Which record can be updated

Situation before updateResult
A chain, read, reade, readp or readpe that returned a record and locked itAllowed
The read used (n)Not allowed. The record is not locked
The read failed or reached end of fileNot allowed. Read the record again with locking
Another operation on the same file between the read and the updateNot allowed. IBM says none should be performed
Two update operations in a rowNot allowed. Read the record again first
name is not the record format that was last readError

An update with no prior successful read fails with status 1221, update operation attempted without a prior read.

Update some fields

To change only some fields, name them in %fields. IBM says to use %fields when only some of the fields of a record are to be updated.

chain %kds(keyDs) ordWork;
if %found(ordWork);
  ORDSTS = 'H';
  update ordRec %fields(ORDSTS);
endif;

Update from a data structure

Read into a data structure and update from it. Define it with likerec on the same record format. For update, the second parameter can be *input, *output or *all, or omitted.

chain %kds(keyDs) ordWork ordData;
if %found(ordWork);
  ordData.ORDSTS = 'S';
  update ordRec ordData;
endif;

WRITE

write adds a record built from the current values of all the fields in the record format. It does not need a prior read. The file must be declared with *output.

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

To write from a data structure, define it with likerec(ordRec : *output) or *all.

dcl-ds newRec likerec(ordRec : *output);

newRec.CUSTKEY = 'C0003';
newRec.ORDNO = 5;
newRec.ORDSTS = 'N';
write ordRec newRec;

Duplicate keys

If the file has unique keys and the key already exists, the write fails with status 1021. Code (e) and test %error, then read the status.

CUSTKEY = 'C0001';
ORDNO = 1;
ORDSTS = 'N';
write(e) ordRec;
if %error;
  // %status(ordWork) is 1021: a record with this key already exists
endif;

Without (e) or ER, the error goes to the program’s default file error handling.

DELETE

delete removes a record permanently. The file must be declared with *delete. There are two forms.

After a chain or a read, name the record format to remove the record that was just read. The record must have been locked by that input operation.

keyDs.CUSTKEY = 'C0003';
keyDs.ORDNO = 4;
chain %kds(keyDs) ordWork;
if %found(ordWork);
  delete ordRec;
endif;

With a search argument, delete finds and removes the record with that key, and %found says whether there was one.

keyDs.CUSTKEY = 'C0003';
keyDs.ORDNO = 5;
delete %kds(keyDs) ordRec;
if not %found(ordWork);
  // no record had that key
endif;

On IBM i, a read after a successful delete returns the record after the deleted one, so a delete inside a read loop does not skip a record.

Status codes to handle

Code (e) and test %error, then use %status for the code. These are the codes in the IBM i 7.5 reference that apply to disk file changes.

StatusMeaningTypical cause
1021A record that already exists was writtenwrite of a duplicate key in a file with unique keys
1022Referential constraint errorwrite, update or delete that breaks a constraint
1023, 1024Error in a trigger program, before or after the operationA trigger on the file failed
1218Record already lockedA read or chain of a record that another job holds
1221Update attempted without a prior readupdate with no locked record

UPDATE, WRITE and DELETE compared

updatewritedelete
Needs a prior locked readYesNoOnly without a search argument
Usage keyword*update*output*delete
NamesThe record format last readA record formatA record format or file, with a key or not
Result test%error with (e)%error with (e)%found with a key, %error with (e)

Common mistakes

  • Calling update after chain(n) or read(n), or after a read that found nothing.
  • Declaring *update and expecting delete to work. Free-form code needs *delete.
  • Writing to a file declared without *output.
  • Not coding (e) where a duplicate key is possible, so the program ends on status 1021.
  • Doing another operation on the file between the read and the update.
  • Updating twice from one read.
  • Using delete with a key but without testing %found.

FAQ

Which record does UPDATE change?

The last record that a locking input operation retrieved from that file. Nothing else should be done on the file in between.

How do I change only one field?

Change the field, then code update ordRec %fields(ORDSTS); with the fields you want written.

What happens when WRITE finds a duplicate key?

In a file with unique keys, status 1021 is set. Without (e) or an ER indicator, the default file error handling takes over. With (e), test %error.

Summary

  • update rewrites the last locked record read, write adds a record, and delete removes the current record or the record with a given key.
  • Declare the file with *update, *output and *delete as needed. Free-form code must name *delete.
  • Read with a lock, change the fields, then update. Use %fields to limit the fields written.
  • Code (e) where a duplicate key or a lock is possible, and test %error and %status.
  • For reading and positioning, see the RPGLE READ, READE and READP Opcode Reference and the RPGLE SETLL and SETGT Opcode Reference, and for the other file operations the RPGLE File I/O Opcodes Reference.

Leave a Comment

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

Scroll to Top