Let's explore how arrays in modern free-form RPGLE can be searched, sorted, and used in embedded SQL fetches. These techniques elevate your RPGLE code with cleaner logic and performance optimization.
1. Searching Arrays
RPGLE provides built-in functions for efficient array searching:
A. %LOOKUP
— For Unsorted Arrays
Use this when you have an unsorted array and need to find the index of an exact value.
**FREE
Dcl-S Codes Char(5) Dim(5) Inz('A100':'B200':'C300':'D400':'E500');
Dcl-S Target Char(5) Inz('C300');
Dcl-S idx Int(3);
idx = %LOOKUP(Target: Codes);
If idx > 0;
Dsply ('Found at position: ' + %Char(idx));
Else;
Dsply ('Value not found');
Endif;
*InLR = *On;
Return;
-
%LOOKUP
returns the position (1‑based) if found, or 0 otherwise.
B. %SEARCH
— For Pattern Matching
Perfect for when you're looking for a substring or pattern in character arrays.
**FREE
Dcl-S Messages Char(30) Dim(3) Inz('Error 404':'OK 200':'Warning 300');
Dcl-S position Int(3);
position = %SEARCH('200': Messages);
If position > 0;
Dsply ('"200" found in: ' + Messages(position));
Endif;
2. Sorting Arrays
A. Compile-Time Sorted Arrays (ASCEND
/ DESCEND
)
Sort your arrays at compile time automatically:
**FREE
Dcl-S AlphaCodes Char(5) Dim(5) Ascend Inz('D400':'B200':'E500':'A100':'C300');
Dsply ('First code after sort: ' + AlphaCodes(1)); // Displays 'A100'
B. Run-Time Sorting via RPGLE Utilities
For dynamic sorting, IBM i provides QSort
in the qsort
service program. Here's a simplified use:
**FREE
Dcl-S Numbers Packed(5:0) Dim(10);
// Initialize array...
// Call QSort (requires prototype definitions)
QSort(pArray: %Elem(Numbers): %Size(Numbers:*): *Off);
// Now Numbers is sorted
(Note: You'll need to define the QSort prototype or use a sorting service program like QUSRSORT.)
3. Using Arrays with Embedded SQL Fetch
In RPGLE versions with embedded SQL, it's possible to fetch multiple rows into an array—a useful technique when you need to retrieve a limited dataset into memory.
Example: FETCH INTO Array (IBM i 7.3 TR7, 7.4 TR1+)
**FREE
exec sql
set option commit = *NONE;
Dcl-S CustNames Char(50) Dim(100);
Dcl-S Counter Int(10) Inz(0);
exec sql
declare C1 cursor for
select name from customers
where city = 'PARIS'
order by name
fetch first 100 rows only;
exec sql
open C1;
dow Counter < %Elem(CustNames);
exec sql
fetch next from C1 into :CustNames(Counter + 1);
if sqlcode = 0;
Counter += 1;
else;
leave;
endif;
enddo;
exec sql close C1;
for i = 1 to Counter;
Dsply 'Customer ' + %Char(i) + ': ' + CustNames(i);
endfor;
*InLR = *On;
Return;
This example shows:
-
A cursor that retrieves ordered customer names.
-
Fetching each name into the
CustNames
array. -
Stopping when no more rows match or the array is full.
Summary Table
Scenario | Technique | Key Functionality |
---|---|---|
Exact search in array | %LOOKUP |
Finds position of exact match |
Pattern search | %SEARCH |
Matches substring or pattern |
Compile-time sorting | ASCEND / DESCEND in declaration |
Automatically orders array at compile time |
Run-time sorting | QSort (or equivalent) |
Sorts any array during execution |
Bulk SQL fetch into array | Embedded SQL with cursor and array fetch | Efficiently loads multiple DB rows |