Just my 2 cents worth, and attempt to answer some of your ancillary questions that may not have been addressed.
Not exactly, if I understand your question. When an END TRANSACTION statement is executed, any updates to records on hold are committed to the database and all held records are released. So the number of “locks” is immediately reduced to zero. In your original example, the “locks” count would start increasing again for every new record read until one meets the update criteria and it is updated and ET’ed. However, with the GET method shown by Douglas, (my preference too) the number of held records is never more than 1 at a time, so the “locks” count is never > 1. A more advanced, slightly more efficient method would be to use an #ET-COUNTER you increment for each record you GET and UPDATE, and then only issue an ET when #ET-COUNTER > 50, and then reset #ET-COUNTER. You also have to add an ET after the END-READ, just in case. It’s only worth doing this if you are updating lots of records.
Since the GET rereads the record into the VIEW buffer, you should put the MOVE for any fields to be updated after the GET and before the UPDATE. If MOVE is before the GET, the values will just be overlaid with the original values.
That depends on the IF … END-IF, I guess and this exact coding. You can mimic the logic of ACCEPT with an IF … END-IF for most situations by adding an IGNORE ELSE ESCAPE TOP to the IF, for example:
RD1. READ MY-VIEW WITH DESC-FIELD-1 GE #INI-SCOPE
IF INI-DATE GE 20220412
AND INI-DATE LE 20220416
AND CONTROL-BUSINESS-FIELD-1 EQ 1
IGNORE /* Accept and process record
ESCAPE TOP /* Reject record
MY-GET. GET MY-VIEW *ISN(RD1.)
MOVE 1 TO CONTROL-BUSINESS-FIELD-8
ADD 1 TO #AMOUNT-UPDATED
MOVE *COUNTER (RD1.) TO #AMOUNT-READ
Yes the value of *COUNTER is available outside the loop. But always best to qualify with the READ label, *COUNTER (RD1), in case there are multiple Reads so Natural doesn’t get confused which *COUNTER you are referring to.
Great tip from Wolfgang, always a good idea to set an exit criteria of some kind for READ loops, either with an ENDING AT #END-KEY or TO #END-KEY, or you could put an IF test … ESCAPE BOTTOM (RD1.) END-IF before the ACCEPT statement. Unless you know the data and you will always have to read to the end of the descriptor from your starting point #INI-SCOPE to find all records that need to be updated.
Hope that helps more than confuses…