Defining a table loads the cheat sheet; searching is asking it questions thousands of times per run. The SEARCH statement names a TABLE file, supplies a WITH key from the current transaction or working storage field, and names GIVING to receive DESC bytes when binary search finds a matching ARG. Broadcom signals success or failure through the table file presence test—IF DEPTTAB after SEARCH DEPTTAB, not EOF semantics and not a return code variable beginners expect from other languages. Miss handling matters: GIVING does not auto-clear on failure, so a prior successful decode can print on the wrong row when you skip IF NOT. This page teaches SEARCH syntax placement in JOB, PROGRAM, and SCREEN, multiple lookups per record, numeric versus alphanumeric key pitfalls, performance characteristics of in-memory binary search, integration with report LINE and error tallies, and debugging techniques when QA swears the code is on the reference file yet SEARCH disagrees.
1SEARCH table-file-name WITH search-field GIVING result-field
table-file-name must be a FILE declared with TABLE. search-field is typically a field from the current input record or working storage—must align with ARG length and comparison rules. result-field receives DESC on match; define it in working storage with same length and type as DESC unless compile rules allow implicit conversion. SEARCH is a complete statement—no line continuation peculiarities beyond normal Easytrieve source columns.
123456SEARCH STATES WITH WS-ST-CD GIVING WS-ST-NAME IF STATES * match — WS-ST-NAME holds DESC from table ELSE WS-ST-NAME = 'INVALID STATE' END-IF
IF STATES is true when SEARCH found ARG equal to WS-ST-CD. IF NOT STATES handles miss path. Some shops use nested IF in procedures; others increment error counters on NOT path for audit trailers. Never PRINT GIVING field on miss without explicit default MOVE—stale data is a production incident waiting for the first new code added only to transaction file, not table.
Runtime assumes ARG sorted ascending at table build. Search picks middle key, compares WITH, eliminates half the table, repeats—O(log n) per call. Unsorted tables produce arbitrary wrong matches because eliminated halves may contain the real key. Duplicates break uniqueness assumptions—define data quality rules prohibiting them. Searching does not sort tables at runtime; fix definition data instead.
1234567891011121314DEFINE WS-DESC W 40 A DEFINE ERR-CNT W 5 N 0 JOB INPUT TRANS FILE SEARCH PROD-TAB WITH PROD-CODE GIVING WS-DESC IF NOT PROD-TAB ADD 1 TO ERR-CNT WS-DESC = '** UNKNOWN PRODUCT **' END-IF SEARCH TAX-TAB WITH TAX-CODE GIVING WS-TAX-LABEL IF NOT TAX-TAB WS-TAX-LABEL = 'TAX N/A' END-IF PRINT DETAIL-RPT
Two SEARCH calls decode independent attributes per transaction. ERR-CNT accumulates product misses for trailer reporting. Each SEARCH has its own presence test. Order of SEARCH calls only matters if later logic overwrites GIVING targets reused as WITH in subsequent SEARCH—use distinct working storage fields when chaining decodes.
| Operand | Must match | Common bug |
|---|---|---|
| WITH | ARG length and type rules | Shorter WITH truncates compare |
| GIVING | DESC length and type | Smaller GIVING truncates description |
| Numeric keys | Leading zero policy vs instream | 903 vs 0903 mismatch |
PROGRAM activities SEARCH before CALL or DISPLAY of shared modules—useful when one decode routine serves several JOB names. SCREEN activities SEARCH when online maps show descriptions for codes users type. Same syntax; presence tests branch to message fields or cursor highlight on invalid codes. TABLE load already occurred at activity initiation—SEARCH is immediate.
| Strategy | When to use |
|---|---|
| Default literal in ELSE | Report must print even with bad codes |
| Increment error counter | Audit trail of bad transactions |
| SKIP or omit PRINT | Strict validation—reject bad rows |
| WRITE to error file | Downstream remediation queue |
Programs often define DEPT-TAB, LOC-TAB, and ERR-TAB together. Each SEARCH is independent—no cross-table join. Hierarchical decode may SEARCH region table then branch to branch table with composite key in WITH built from prior fields. Build composite keys in working storage with explicit MOVE and concatenation before SEARCH when ARG spans multiple conceptual parts.
Binary search on five thousand keys costs roughly twelve compares—negligible versus disk GET. One million input rows with two SEARCH calls each on modest tables still dominates CPU less than sort or unindexed master READ per row. Memory holds full table regardless of how many keys you actually hit—oversized tables hurt region, not per-search CPU. Profile before replacing TABLE with SQL for small lists based on folklore.
| Approach | Per-lookup cost | Fit |
|---|---|---|
| SEARCH TABLE | Memory binary search | Static modest reference |
| READ INDEXED | Disk I/O per key | Large volatile master |
Searching the table is whispering a secret code to the cheat sheet and listening for the answer. SEARCH is the whisper. WITH is the code you whisper. GIVING is the hand that catches the answer written on the sheet. IF the sheet found your code, the hand holds the right word. IF NOT, you must decide what to say instead—maybe UNKNOWN—because the hand might still be holding yesterday's answer from a different code if you do not clear it. You can whisper to many cheat sheets for one kid's card: one for lunch menu, one for bus route, each with its own IF found check.
1. Correct SEARCH syntax is:
2. After SEARCH, success is tested with:
3. SEARCH compares WITH to:
4. On SEARCH miss without IF NOT handling:
5. Multiple SEARCH calls per input record are: