SEARCH & SEARCH ALL

18.1 SEARCH (serial)

Starts at the current index value (so SET ... TO 1 first) and advances one entry at a time. Multiple WHENs are allowed, any condition can be used, and the table need not be sorted; O(n).

SET RATE-IDX TO 1
           SEARCH WS-RATE-ENTRY
               AT END
                   DISPLAY "Rate code not found: " WS-IN-CODE
               WHEN WS-RATE-CODE(RATE-IDX) = WS-IN-CODE
                   MOVE WS-RATE-PCT(RATE-IDX) TO WS-PCT
           END-SEARCH

18.2 SEARCH ALL (binary)

The table must have ASCENDING/DESCENDING KEY and INDEXED BY, and the data must actually be sorted on the key (otherwise results are unpredictable).

Only one WHEN; conditions must be equality tests on keys (combined with AND). No need to SET the index first. O(log n) — much faster for large tables.

01  WS-STATE-TABLE.
           05  WS-STATE-COUNT      PIC S9(4) COMP VALUE 0.
           05  WS-STATE OCCURS 1 TO 60 TIMES
                        DEPENDING ON WS-STATE-COUNT
                        ASCENDING KEY IS WS-STATE-CODE
                        INDEXED BY ST-IDX.
               10  WS-STATE-CODE   PIC XX.
               10  WS-STATE-NAME   PIC X(20).
      * ...
           SEARCH ALL WS-STATE
               AT END
                   MOVE "UNKNOWN" TO WS-OUT-NAME
               WHEN WS-STATE-CODE(ST-IDX) = WS-IN-STATE
                   MOVE WS-STATE-NAME(ST-IDX) TO WS-OUT-NAME
           END-SEARCH

18.3 Loading a lookup table from a file

A common pattern: read a sorted reference file at startup into a table, ADD 1 to the DEPENDING ON counter for each record, move the fields into the new last entry, and use SEARCH ALL for each transaction. Always check for table overflow (counter already at the OCCURS maximum) and stop with a high return code rather than overwriting storage.