The SEARCH statement searches an indexed table for a specific table entry. The search may be sequential or binary (SEARCH
or SEARCH ALL). The search terminates when either a match is found (first match), or when the entire table has been searched.
Note: This manual entry includes code examples and highlights for first-time users following the
General Rules section.
Format 1
SEARCH table-name [ VARYING index-item ]
[ AT END statement-1 ]
{ WHEN srch-cond {statement-2 } } ...
{NEXT SENTENCE }
[ END-SEARCH ]
Format 2
SEARCH ALL table-name
[ AT END statement-1 ]
WHEN { tbl-item {IS EQUAL TO} value }
{ {IS = } }
{ cond-name }
[ AND { tbl-item {IS EQUAL TO} value } ] ...
{ {IS = } }
{ cond-name }
{ statement-2 }
{ NEXT SENTENCE }
[ END-SEARCH ]
Syntax Rules
- table-name is a data item that must contain an OCCURS clause including an INDEXED BY phrase.
table-name must not be subscripted in the SEARCH statement. In Format 2,
table-name must also contain the KEY IS phrase in its OCCURS clause.
- index-item is a numeric integer data item or an index name. It may not be subscripted by the first index name in the INDEXED BY phrase
in the OCCURS clause of table-name.
- srch-cond is a conditional expression.
- statement-1 and
statement-2 are imperative statements.
- value may be a data item, a literal, or an arithmetic expression. It must be legal to compare value with
tbl-item. No data item in value may be referenced in the KEY IS phrase in the OCCURS clause of
table-name, nor may it be subscripted by the first
index-name associated with table-name.
- cond-name is a condition-name (level 88) that must be defined as having only a single value. The
condition-variable associated with
cond-name must appear in the KEY IS phrase in the OCCURS clause of
table-name.
- tbl-item must be subscripted by the first index-name associated with
table-name along with other subscripts as required. It must be referenced in the KEY IS phrase in the OCCURS clause of
table-name.
tbl-item may not be reference modified.
- In Format 2, when a
tbl-item or a cond-name is referenced, all preceding data-names in the KEY IS phrase in the OCCURS clause of table-name (or their
associated
condition-names) must also be referenced.
Format 1 General Rules
- The Format 1 SEARCH statement searches a table serially starting with the current index setting.
- If the
index-name associated with table-name contains a value that is higher than the highest occurrence number for
table-name, the search terminates immediately. If the AT END phrase is specified,
statement-1 executes. Control then passes to the end of the SEARCH statement.
- If the
index-name associated with
table-name contains a valid occurrence number, the SEARCH statement evaluates the WHEN conditions (srch-cond) in the order they appear. If no condition is satisfied, the
index-name associated with
table-name is set to the next occurrence number. The evaluation process is then repeated. This process ends when a condition is satisfied
or an occurrence number outside of the range of
table-name is generated. In this second case, processing continues as in step (1a) above.
- When a
srch-cond is satisfied, the SEARCH terminates and the associated
statement-2 executes (or control passes to the next sentence if NEXT SENTENCE is used). The
index-name associated with
table-name remains set at its current value. Control then passes to the end of the SEARCH statement.
- If there is no VARYING phrase specified, the
index-name used for the search is the first
index-name in the INDEXED BY phrase associated with
table-name. Other
index-names associated with
table-name remain unchanged.
- If the VARYING phrase is specified, and
index-item names an index-name associated with
table-name, then that
index-name is used for the search operation. If
index-name names some other
index-name or a numeric data item, that item is incremented by 1 every time the
index-name associated with the search operation is incremented. The
index-name specified in rule 2 is used for the search procedure.
Format 2
- A Format 2 SEARCH performs a binary search of an ordered table. It yields predictable results only when:
- the data in the table has the same order as specified by the KEY IS phrase associated with
table-name
- the contents of the keys in the WHEN phrase identify a unique table element
- The initial value of the
table-name index-name is ignored. It is varied in a non-linear manner by the SEARCH operation until the WHEN conditions are satisfied
or the table has been searched.
- If the WHEN phrase conditions are not satisfied for any index setting, control passes to the AT END phrase
statement-1, if any, or to the end of the SEARCH statement. The setting of the
table-nameindex-name is not predictable in this case.
- If all of the WHEN phrase conditions are satisfied for an index setting, control passes either to the associated
statement-2 or to the next sentence, whichever is specified. The
table-nameindex-name indicates the occurrence number that satisfied the conditions.
- The
index-name used for the search is the first index-name listed in the INDEXED BY phrase associated with
table-name. Other
index-names remain unchanged.
Code Example 1
In this example SEARCH is used to conduct a sequential search of the table for the first match. The index data item must be
assigned an initial value by the program. Note that subsequent searches of the table for additional matches may be made if
the value of the search index is saved after a match.
Assume the following table data item:
01 FRUIT-TREE-INVENTORY.
05 FRUIT-TREE-TABLE
OCCURS 100 TIMES
INDEXED BY FTT-INDEX.
10 FT-NAME PIC X(25).
10 FT-CODE PIC X(5).
10 FT-PRICE PIC 9(5)V99.
10 FT-COUNT PIC 999.
*05 table name is specified by SEARCH
*OCCURS and INDEXED BY required for SEARCH
Assume that FRUIT-TREE-TABLE has been loaded.
*use SET to initialize the index
SET FTT-INDEX TO 1.
SEARCH FRUIT-TREE-TABLE
*handle no match in table
AT END DISPLAY "Variety not found."
*test for match
WHEN FT-NAME (FTT-INDEX) = TREE-NAME
*match found, perform action
PERFORM DISPLAY-INVENTORY-ITEM
END-SEARCH.
Example 2
In this example a WHEN clause is used in a sequential search to test for an
end of table (AT END equivalent) condition. Note that when the table being searched is not full (has table elements at the end that have
not been filled), searching the table into the unfilled space will give unpredictable results. You can search a partially
filled table by determining the position of the last valid entry in the table and then using a WHEN clause in the SEARCH statement
to test for when the search process traverses past the last valid entry.
Assume the same table declaration as in example 1. Assume, also, that the program has verified the table entries and has saved
the subscript value of the last valid entry in a variable named LAST-VALID-ENTRY.
*initialize the search index
SET FTT-INDEX TO 1.
SEARCH FRUIT-TREE-TABLE
*test for match
WHEN FT-NAME (FTT-INDEX) = TREE-NAME
*match found, perform action
PERFORM DISPLAY-INVENTORY-ITEM
*test for indexing into unfilled table space
WHEN FTT-INDEX > LAST-VALID-ENTRY
*exit the SEARCH statement
NEXT SENTENCE.
if ftt-index > last-valid-entry
display " variety not found".
Code Example 3
In this example SEARCH ALL is used to conduct a binary search of an ordered table. Binary searches require sequential, ordered
tables. The table definition must include an ASCENDING or DESCENDING KEY clause. The search terminates upon first match, and
there is no way to continue the search to find a second match. Binary searches are best suited to large tables (typically
50 records or more). When used to search large tables, the binary search method will, on average, find a table record much
more quickly than will a sequential search. For example, a table containing 1000 records will need to perform no more than
ten comparisons to find a match.
Assume the following table data item:
01 FRUIT-TREE-INVENTORY.
05 FRUIT-TREE-TABLE
*OCCURS required for SEARCH
OCCURS 100 TIMES
*ASCENDING/DESCENDING KEY required
*for SEARCH ALL
ASCENDING KEY IS FT-NAME
*INDEXED BY required for SEARCH
INDEXED BY FTT-INDEX.
10 FT-NAME PIC X(25).
10 FT-CODE PIC X(5).
10 FT-PRICE PIC 9(5)V99.
10 FT-COUNT PIC 999.
Assume the table has been loaded.
*FTT-INDEX is initialized by SEARCH ALL
SEARCH ALL FRUIT-TREE-TABLE
*Handle no match in table.
AT END DISPLAY "Variety not found"
*Test for match
WHEN FT-NAME (FTT-INDEX) = TREE-NAME
*Match found, perform action
PERFORM DISPLAY-INVENTORY-ITEM
END-SEARCH.
Code Example 4
This example demonstrates how to use SEARCH or SEARCH ALL to search multi-dimensional tables:
SEARCH is not, by itself, equipped to perform multi-dimensional table searches. One approach to accomplishing multi-dimensional
table searches is to use SEARCH in conjunction with PERFORM/VARYING (as the following example will illustrate). When used
together, SEARCH handles lookups at the innermost level (dimension) of the table structure and PERFORM/VARYING is used to
manage stepping through the outer levels of the table.
Assume the following table data item:
01 TREE-INVENTORY.
05 NURSERY-YARD |inventory location,
OCCURS 10 TIMES |"outer" table
INDEXED BY YARD-IDX.
10 TREE-TABLE |tree type,
OCCURS 100 TIMES |"inner" table
INDEXED BY TT-IDX.
15 FT-NAME PIC X(25).
15 FT-CODE PIC X(5).
15 FT-PRICE PIC 9(5)V99.
15 FT-COUNT PIC 999.
Assume the table has been loaded.
MOVE "N" TO TREE-FOUND.
PERFORM SEARCH-TREE-INVENTORY
*step through the outer table
VARYING YARD-IDX FROM 1 BY 1
UNTIL YARD-IDX > 10 OR TREE-FOUND = "Y".
IF TREE-FOUND = "N" |note that this code
PERFORM NO-TREE-FOUND. |executes after the
END-IF. |search is complete
{ . . . }
SEARCH-TREE-INVENTORY.
SET TT-IDX TO 1.
SEARCH TREE-TABLE
WHEN TREE-TABLE(YARD-IDX,TT-IDX) = TREE-NAME
*note that both the inner and outer table
*indexes are required
PERFORM DISPLAY-INVENTORY-ITEM
MOVE "Y" TO TREE-FOUND
END-SEARCH.
If the inner table is ordered and large enough to benefit from a binary search, use SEARCH ALL.
Highlights for First-time Users
- The table name identifier used in SEARCH must be the table name specified in the OCCURS phrase of the table declaration. You
cannot use the 01 table label that starts the table declaration.
- If END-SEARCH is used NEXT SENTENCE cannot be used. Where possible it is best to use the sentence terminator, END-SEARCH.
Unintended logic errors are often introduced by the use of NEXT SENTENCE and are easily avoided by the use of END-SEARCH.
Sequential Searches (SEARCH)
- A sequential search is conducted as follows:
- The search cycle begins by verifying that the value of the index data item falls within the range of the table size (the range
is from 1 to the value specified in the OCCURS clause of the record definition).
- If the index value is valid, then each WHEN condition phrase is evaluated until either a match is found or until all WHEN
conditions have been tested.
- If there is no match, the value of the index is incremented by one, validated (as in step a), and the WHEN condition evaluation
cycle is repeated.
- Steps a - c iterate until either a match is found or the value of the index exceeds the table range, indicating that the entire
table has been searched.
- If a match is found, the search terminates and the imperative statement associated with the WHEN clause is executed. Program
execution then resumes immediately after the SEARCH statement. Note that the value of the index data item remains set to the
value of the subscript of the matched entry.
- If the value of the search index ever becomes less than one or greater than the table size, the search terminates, the optional
AT END statement, if present, is executed, and program execution continues immediately after the SEARCH statement.
- The index data item named in the INDEXED BY clause is used to index the table in the sequential search and must be explicitly
initialized in the program. Use SET to assign the initial value. When the search results in a match, the index data item remains
set to the table subscript of the matching entry. Saving or preserving this value makes it possible to make another search
of the table for a subsequent match.
Initializing the index data item:
- If the entire table is to be searched, the index data item should be assigned, using SET, the value 1, thereby starting the
search with the first record.
- If the search is to begin with an entry other than the first, then the index data item should be assigned the value of the
position of the first table entry to be checked. For example, to start the search at table entry 10, assign the value 10 to
the index data item.
- If, after a search finds a match, you want to make an additional search of the table to find a subsequent match, the value
of the index data item should be preserved and then reassigned so that the next search begins at 1 + index-item.
- When searching tables that are not full (do not contain valid entries for every occurrence in the table), use a WHEN clause
to test for the actual end-of-table condition. If the search is allowed to proceed into the unused portion of the table, garbage
values in the unfilled table space will give unpredictable results. See code example 2.
- The relational match conditions associated with each WHEN clause may be connected with the logical connectors AND or OR thereby
specifying multiple or alternate match conditions. For example:
WHEN NAME = SEARCH-NAME OR SIZE < MAX-SIZE
- Use of the VARYING phrase: The VARYING phrase allows alternate or multiple indexes to be incremented by the search loop. If
VARYING is omitted, the first index-item defined in the INDEXED BY phrase of the OCCURS clause (for the table) is incremented.
If the VARYING phrase is included, the index item named after VARYING is incremented, as well as the first named index in
the INDEXED BY phrase, with one exception. If the index named after VARYING is also named in the INDEXED BY phrase, then it
is the only index incremented.
Binary Searches (SEARCH ALL):
- The binary search is conducted as follows:
- The search begins at the midpoint of the table (for example, 50 of 100) and compares the value of the table entry with the
search item to determine if there is a match.
- If there is no match, SEARCH determines whether the search item is logically located in the upper or lower half of the table
(0-49, or 51-100).
- SEARCH then finds the midpoint of the half that logically contains the search item and determines if the table element at
the midpoint matches the search item.
- If there is no match, SEARCH again determines whether the search item is logically located in the upper or lower half of the
remaining range.
- This process iterates until the search item is found or until it is determined that the table does not contain the search
item (the remaining table range becomes null).
- If at any time a match is found, the search immediately terminates and the imperative statement associated with the WHEN clause
is executed. Program execution then resumes immediately after the SEARCH statement.
- Binary searches require sequential, ordered tables (via use of the ASCENDING/DESCENDING KEY phrase). The table must be ordered
as specified by the KEY IS phrase of the table definition.
- The matching conditions of the WHEN clause must identify a unique table entry.
- Binary searches are best suited to large tables (typically 50 records or more) where the binary search algorithm significantly
reduces the average number of lookups per match.
- Unlike a sequential search, the binary search format permits only one WHEN clause.
- Because only one WHEN clause is permitted and because the index value is automatically set by the program, it is not possible
to SEARCH partially full tables.
- The SEARCH ALL match conditions are very restrictive. Match condition evaluation is restricted to evaluation of a
condition-name, which can represent only a single value (no range or sequence of values permitted), or a condition which tests for equality.
- The table data item and the index must be on the left side of the condition statement.
- Multiple condition tests are permitted but can be connected only with an AND (no OR).
- Any table item or
condition-name referenced must be named in the KEY IS phrase of the OCCURS clause of the table definition.
- The VARYING option is not permitted.
- When a match is found, the index retains the value of the table subscript of the matched entry. If no match is found the value
of the index is unpredictable.