Get RRN in RPGLE

23 Views


In RPGLE, %RRN is a built-in function that returns the relative record number (RRN) of the last record read or written to a file. It is a powerful tool for navigating and manipulating files, especially physical files that are not keyed.

 

What is a Relative Record Number (RRN)?

 

A Relative Record Number is a unique, system-assigned integer that identifies the physical location of a record within a physical file.

  • The first record in a file has an RRN of 1, the second is 2, and so on.

  • Unlike keys, RRNs are not necessarily in the order the records were created, as deleted records can have their space (and RRN) reused.

  • RRNs are an "arrival sequence" identifier. When a new record is added, it typically gets the next available RRN. If a record is deleted, its RRN may be reused for a new record, depending on the file's REUSEDLT attribute.

 

How to Use %RRN

 

The %RRN built-in function is used to retrieve the RRN of the record that was most recently accessed by a file operation.

The basic syntax is:

%RRN(file_name)

Here are some common use cases:

 

1. Navigating a File by Position

 

%RRN is the primary way to perform random access on a non-keyed physical file. You can use it with the CHAIN operation to directly access a specific record by its RRN.

Example:

Code snippet

**FREE
Dcl-F MyFile Usage(*Input) RECNO(RRNField); // RECNO keyword is optional, but common

Dcl-S SavedRRN packed(7:0);

// Read the first record
Read MyFile;
// Get its RRN
SavedRRN = %RRN(MyFile);

// Read the next record
Read MyFile;
// Get its RRN
SavedRRN = %RRN(MyFile);

// Now, chain to the first record you read
Chain SavedRRN MyFile;
If %Found(MyFile);
   Dsply 'Successfully chained back to a record.';
EndIf;
  • The RECNO(RRNField) keyword on the Dcl-F specification links a program variable to the file's RRN. This variable is automatically updated after each file operation. This is a classic RPG III/400 method, and while it still works, using the %RRN BIF is the modern, preferred approach.

 

2. Finding a Record's RRN after a Read

 

After a READ or READP operation on a file, %RRN will contain the RRN of the record that was just retrieved. This is particularly useful when you are processing a file in a non-keyed or logical-file-keyed sequence and want to know the physical location of the record.

Example:

Code snippet

**FREE
Dcl-F MyLogicalFile Usage(*Input) Keyed;
Dcl-S SavedRRN packed(7:0);

// Use SETLL to find the first order for a customer
Setll 'CUST123' MyLogicalFile;
Reade 'CUST123' MyLogicalFile;

Dow not %EOF(MyLogicalFile);
   // After the READE, %RRN holds the RRN of the record we just read.
   SavedRRN = %RRN(MyLogicalFile);
   Dsply ('Order for CUST123, RRN: ' + %Char(SavedRRN));
   Reade 'CUST123' MyLogicalFile;
EndDo;

 

3. Using RRN for File Updates/Deletes

 

While it's generally recommended to use keys for file access and modification, %RRN can be used in CHAIN operations for UPDATE or DELETE when you're working with a file that doesn't have a good key or when the RRN is a convenient handle.

Example:

Code snippet

**FREE
Dcl-F MyFile Usage(*Update) RECNO(RRNField);

Dcl-S TargetRRN Packed(7:0);

// Assume TargetRRN holds a previously retrieved RRN value
TargetRRN = 1234;

// Use CHAIN to lock and retrieve the record by its RRN
Chain TargetRRN MyFile;
If %Found(MyFile);
   // Modify the record
   SomeField = 'New Value';
   // Update the record based on its RRN
   Update MyFile;
EndIf;

 

Important Considerations

 

  • RRNs can change: A file reorganization (RGZPFM) will renumber all RRNs in a physical file, so you should never store RRNs as persistent data (e.g., in another database table) unless you can guarantee the file will not be reorganized.

  • Performance: Chaining by RRN is often the fastest way to access a single record because it directly accesses the physical location on disk, bypassing any index lookups.

  • Keyed vs. Non-keyed: %RRN works on both keyed and non-keyed files, but its primary purpose is for files without a logical key. For keyed files, it's generally safer and more robust to use the key itself in operations like CHAIN, SETLL, SETGT, etc., as the key is stable even after a file reorganization.

Post Comments