Key Takeaways: Table Handling and Searching
-
OCCURS defines tables at compile time. It can appear on levels 02-49, never on 01, 66, 77, or 88. Storage is allocated for the maximum number of entries.
-
Indexes outperform subscripts because they store byte displacements rather than element numbers, eliminating runtime multiplication. Use INDEXED BY for heavily searched tables and manipulate indexes only with the SET statement.
-
SEARCH performs serial (linear) search, starting at the current index position. You must SET the index to 1 before each search unless you intentionally start mid-table. Supports multiple WHEN clauses and complex conditions including OR.
-
SEARCH ALL performs binary search in O(log n) time but requires: ASCENDING/DESCENDING KEY declared, data actually sorted, equality-only conditions, a single WHEN clause (AND is allowed, OR is not). Do not SET the index before SEARCH ALL.
-
Multi-dimensional tables use nested OCCURS clauses (up to 7 levels). Calculate total memory carefully. Access elements with multiple subscripts/indexes separated by commas.
-
OCCURS DEPENDING ON creates variable-length tables. The DEPENDING ON item must precede the OCCURS item. Always validate the DEPENDING ON value is within range before any table operation.
-
Three loading strategies exist: hardcoded with REDEFINES (small, stable data), file-loaded (large or frequently changing data), and copybook-based (shared definitions across programs).
-
Choose the right search strategy: Direct indexing for O(1) when keys map to positions. Serial search for small/unsorted tables or complex conditions. Binary search for large sorted tables with equality lookups.
-
Defensive programming is non-negotiable: Validate boundaries, verify sort order, check for overflow during loading, confirm the table is loaded before searching, and always handle AT END conditions.
-
Know the limits: When tables exceed ~100,000 entries or need dynamic updates, consider VSAM, DB2, or shared memory alternatives.