SEARCH Statement

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

  1. 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.
  2. 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.
  3. srch-cond is a conditional expression.
  4. statement-1 and statement-2 are imperative statements.
  5. 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.
  6. 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.
  7. 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.
  8. 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

  1. The Format 1 SEARCH statement searches a table serially starting with the current index setting.
    1. 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.
    2. 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.
    3. 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.
  2. 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.
  3. 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

  1. A Format 2 SEARCH performs a binary search of an ordered table. It yields predictable results only when:
    1. the data in the table has the same order as specified by the KEY IS phrase associated with table-name
    2. the contents of the keys in the WHEN phrase identify a unique table element
  2. 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.
  3. 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.
  4. 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.
  5. 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

  1. 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.
  2. 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)
  1. A sequential search is conducted as follows:
    1. 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).
    2. 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.
    3. 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.
    4. 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.
    5. 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.
    6. 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.
  2. 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:

    1. 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.
    2. 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.
    3. 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.
  3. 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.
  4. 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
  5. 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):
  1. The binary search is conducted as follows:
    1. 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.
    2. 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).
    3. 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.
    4. 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.
    5. 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).
    6. 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.
  2. 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.
  3. The matching conditions of the WHEN clause must identify a unique table entry.
  4. 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.
  5. Unlike a sequential search, the binary search format permits only one WHEN clause.
  6. 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.
  7. 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.
  8. The table data item and the index must be on the left side of the condition statement.
  9. Multiple condition tests are permitted but can be connected only with an AND (no OR).
  10. Any table item or condition-name referenced must be named in the KEY IS phrase of the OCCURS clause of the table definition.
  11. The VARYING option is not permitted.
  12. 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.