| Introduction
|
Aims
| The task of searching a table to determine whether it contains a particular value is a common operation. The method used to search a table depends heavily on how the values in the table are organized. For instance, if the values are not ordered, the table may only be searched sequentially, but if the values are ordered, then either a sequential or a binary search may be used. In COBOL, the SEARCH verb is used for sequential searches and the SEARCH ALL for binary searches. This tutorial introduces the syntax and rules of operation of the SEARCH and SEARCH ALL verbs. It introduces the extensions to the OCCURS clause that are required when the SEARCH or SEARCH ALL is used. It shows how the SET verb may be used to alter the value of an index and it demonstrates how the SEARCH and SEARCH ALL may be used to search a table.
|
Objectives
| By the end of this unit you should -
|
Prerequisites
| Introduction to COBOL Declaring data in COBOL Basic Procedure Division Commands Selection Constructs Iteration Constructs Introduction to Sequential files Processing Sequential files Print files and variable length records Sorting and Merging files Using Tables Creating Tables - syntax and semantics
|
| Occurs clause extensions
|
Introduction
| When the SEARCH and SEARCH ALL are used the normal table declarations are no longer sufficient and the OCCURS clause must be extended with the INDEXED BY phrase and, in the case of the SEARCH ALL, by the KEY IS phrase. The full syntax of the OCCURS clause, including the INDEXED BY and KEY IS phrases is shown below.
|
Full OCCURS clause syntax
|
|
INDEXED BY phrase - notes
| Before the SEARCH or SEARCH ALL can be used to search a table, the table must be defined as having an index item associated with it. The index is specified by the IndexName given in the INDEXED BY phrase. The index defined in a table declaration is associated with that table and is the subscript which the SEARCH or SEARCH ALL uses to access the table. Using an index makes the searching more efficient. Since the index is linked to a particular table, the compiler, taking into account the size of the table, can choose the most efficient representation possible for the index and this speeds up the search. The only entry that needs to be made for an IndexName is to use it in an INDEXED BY phrase. There is no need to define a picture clause for it, because the compiler handles its declaration automatically. Because an index has a special internal representation it cannot be displayed and can only be assigned a value, or have its value assigned, by the SET verb. The MOVE cannot be used with a table index. Normal arithmetic cannot be performed on a table index. The SET verb must be used to increment or decrement the value of an index item.
|
KEY IS phrase - notes
| While the SEARCH performs a sequential search on a table, the SEARCH ALL performs a binary search. But a binary search requires that the table is ordered on some key field. The key field may be the element itself or, where the element is a group item, a field within the element. Before a table can be searched with the SEARCH ALL, the key field must be identified by using the KEY IS phrase in the table declaration. As well as identifying the key field, the KEY IS phrase specifies whether the table is in ascending or descending order.
|
| The SEARCH verb
|
Introduction
| When the values in a table are not ordered, the only way to find the item we seek is to search through the table sequentially, element by element. In COBOL, the SEARCH verb is used to search a table sequentially.
|
SEARCH syntax
|
SEARCH rules
SEARCH notes
|
The SET verb syntax
| The SET verb is used for a number of unrelated purposes. We have already seen how the SET verb may be used to set a condition name to true. This section introduces the versions of the SET verb used to manipulate table indexes. Because an index item has a special internal representation designed to optimize searching, it cannot be used in any type of normal arithmetic operation (ADD, SUBTRACT etc.) or even in a MOVE or DISPLAY statement. For index items, all these operations must be handled by the SET verb. The versions of the SET verb shown below are used to assign a value to an index item, to assign the value of an index item to a variable, and to increment or decrement the value of an index item.
|
SEARCH example 1 |
The example program below accepts an upper case letter from the user and then uses the SEARCH verb to searche a pre-filled table of letters to find and display the position of the letter in the alphabet. Because a table index can be tricky to manipulate (can't display it, can't move it) the program uses the VARYING phrase to vary an ordinary numeric value along with the index. When the letter is found in the table, this item will contain the same value as the index and we can display it without the complications we might encounter with the index item. For instance, to display the value of the index item we would require following code - SET LetterPos TO LetterIdx MOVE LetterPos TO PrnPos DISPLAY LetterIn, " is in position ", PrnPos The example below is not meant to be a practical example of how to find the position of a letter in the alphabet. Nowadays, this task would be accomplished in much the same way as it would in C or Modula-2 except that, in COBOL, we would use the Intrinsic Function - ORD - as shown below. COMPUTE PrnIdx = FUNCTION ORD(LetterIn) - FUNCTION ORD("A") + 1
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Example program 2 |
In this example below, we return to the County Tax Report problem. In the last question we posed in the Using Tables tutorial we asked how the County Tax report problem could be solved if the tax record contained a county name instead of a county code. We noted that the county name had to be converted into a numeric value that we could use as a subscript. In the Using Tables tutorial we used a PERFORM to search through the table to find the numeric equivalent of the county name. In this example we use the SEARCH. The VARYING phrase is used in this SEARCH example so that we don't have to set the Idx to the CountyIdx. We can not use CountyIdx as a subscript for the CountyTaxTable because it is bound to the CountyNameTable.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Searching multi-dimension tables | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Introduction |
When the SEARCH verb is used, the target of the SEARCH must be an item in the table with both an OCCURS clause and an INDEXED BY phrase. The index item specified in the INDEXED BY phrase is the controlling index of the search. The controlling index governs the submission of the elements, or element items, for examination by the WHEN phrase of the SEARCH. A SEARCH can only have one controlling index. Because a SEARCH can only have one controlling index it can only be used to search a single dimension of a table at a time. If the table to be searched is a multi-dimension table then the programmer must control the indexes of the other dimensions. For instance, suppose a hotel keeps an Occupancy Table showing which rooms in the hotel are currently occupied. The table might be described as - 01 HotelOccupanyTable.
02 Floor OCCURS 5 TIMES INDEXED BY Fidx.
03 Room OCCURS 25 TIMES INDEXED BY Ridx.
04 CustomerId PIC 9(6).
04 NumOfOccupants PIC 9.
and we can represent this diagrammatically as follows - Suppose we want to search the table to discover which room is occupied by customer 126789. We can't use the SEARCH to search the whole two-dimension table directly but we can use the SEARCH to search the table floor by floor. In other words, we can treat the table as if it were a collection of floor tables and we use the SEARCH to search all the rooms in a particular floor table. The example program below demonstrates how the SEARCH verb may be used to search the two-dimension HotelOccupancyTable. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The Race Results Example program |
This example demonstrates how the SEARCH may be used to search either of the dimensions of a two-dimension table. Suppose that we want to use a two-dimension table to hold the finishing positions of drivers in fifteen races. The table to hold these details may be described as - 01 RaceResultsTable.
02 Race OCCURS 15 TIMES INDEXED BY Ridx.
03 Venue PIC X(20).
03 RacePos OCCURS 50 TIMES INDEXED BY Pidx.
04 DriverId PIC 9(4).
We can represent this diagramatically as follows -
In the example program below, the first dimension of the table is searched to find the results for a particular venue and then the second dimension, representing the results fo the race at that venue, are searched to find the finishing position of a particular driver.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
In the example above an out-of-line perform was used for the second SEARCH. This was not strictly necessary. The same result could have been achieved with nested SEARCH statements. For instance - SET Ridx TO 1
SEARCH Race
AT END DISPLAY "Venue not found."
WHEN Venue(Ridx) = VenueName
SET Pidx TO 1
SEARCH RacePos
AT END DISPLAY "Driver not in top 50 finishers"
WHEN DriverId(Ridx, Pidx) = DriverIdNum
SET Pos TO Pidx
DISPLAY "In the race at " VenueName
DISPLAY "Driver " DriverIdNum
" finished in position " Pos
END-SEARCH
END-SEARCH | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The SEARCH ALL verb | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Introduction
|
The SEARCH ALL is used when a binary search is required. For this reason, the SEARCH ALL will only work on an ordered table. The table must be ordered on some some key field. The key field may be the element itself or, where the element is a group item, a field within the element. The key field must be identified by using the KEY IS phrase in the table declaration. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SEARCH ALL syntax |
SEARCH ALL rules
SEARCH ALL
notes When the SEARCH ALL is used, the programmer does not need to set the table index to a starting value because the SEARCH ALL controls it automatically. Some problems using the SEARCH
ALL | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
How a binary search works |
A binary search requires that the table to be searched is ordered on some key field. A binary search works by repeatedly dividing the search area into a top and bottom half, deciding which half contains the required item, and then making that half the new search area. It continues halving the search area like this until the required item is found or it discovers that the item is not in the table. The algorithm for the binary search is -
The animation below demonstrates how the binary search works. It uses a search of the letter table described in one of the examples above, as an example. To allow the table to be searched with the SEARCH ALL the description of the table has to be amended to include a KEY IS phrase as shown below. 01 LetterTable.
02 LetterValues.
03 FILLER PIC X(13)
VALUE "ABCDEFGHIJKLM".
03 FILLER PIC X(13)
VALUE "NOPQRSTUVWXYZ".
02 FILLER REDEFINES LetterValues.
03 Letter PIC X OCCURS 26 TIMES
ASCENDING KEY IS Letter
INDEXED BY LetterIdx.
When the table description contains a KEY IS phrase we can search it using the following statement -
The full program for searching the letter table is given below. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Example program |
In this example, we revisit the County Tax Report program once more. This time we use the SEARCH ALL to search the pre-filled table of county names. The new parts of the program are coloured red.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Copyright NoticeThese COBOL course materials are the copyright property of Michael Coughlan. All rights reserved. No part of these course materials may be reproduced in any form or by any means - graphic, electronic, mechanical, photocopying, printing, recording, taping or stored in an information storage and retrieval system - without the written permission of the author. (c) Michael Coughlan Last updated : May 1999
mailto:michael.coughlan@ul.ie | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||