Array Processing and Table
Handling
OBJECTIVES
To familiarize you with:
1. How to establish a series of items using an OCCURS clause.
2. How to access and manipulate data stored in an array or
table.
3. The rules for using an OCCURS clause in the DATA DIVISION.
4. The use of a SEARCH or SEARCH ALL for a table look- up.
CONTENTS
An Introduction to Single-Level OCCURS Clauses
Why OCCURS Clauses Are Used
Rules for Use of the OCCURS Clause
Processing Data Stored in an Array
Using OCCURS with VALUE and REDEFINES Clauses
Printing Data Stored in an Array
CONTENTS
Using an OCCURS Clause for Table Handling
Defining a Table
Storing the Table in WORKING-STORAGE
Looking Up Data in a Table: Finding a Match
Use of the SEARCH Statement for Table and Array Processing
Format of the SEARCH Statement
The INDEXED BY Clause and the SEARCH Statement
Modifying the Contents of an Index
CONTENTS
Using Two WHEN Clauses for an Early Exit from a
SEARCH
Searching for Multiple Matches
Internal vs... External Tables
Looking up Table Data for Accumulating Totals
The SEARCH ... VARYING Option for Processing
Parallel Tables
CONTENTS
The SEARCH ALL Statement
Definition of a Serial Search
Definition of a Binary Search
Format of the SEARCH ALL Statement
ASCENDING or DESCENDING KEY with the SEARCH ALL Statement
CONTENTS
Multiple-Level OCCURS Clause
Accessing a Double-Level or Two-Dimensional Array
Defining a Double-Level or Two-Dimensional Array
Using PERFORM ... VARYING ... AFTER
Using a Double-Level or Two-Dimensional Array for Accumulating
Totals
Performing a Look-Up Using a Double-Level OCCURS
An Introduction to
Single-Level OCCURS Clauses
Why OCCURS Clauses Are Used
SOME USES OF OCCURS
1. Defining a series of input or output fields, each with the same format.
2. Defining a series of totals in WORKING-STORAGE to which amounts
are added; after all data is accumulated.
3. Defining a table in WORKING-STORAGE to be accessed by each
input record.
With a table, we use the contents of some input filed to "look up" the
required data in the table.
Defining Fields with an
With an occurs
clause, we specify the number of items being
Occurs
Clause
defined in the array and the PIC clause of each as follows:
01 TEMP-REC.
05 TEMPERATURE OCCURS 24 TIMES PIC X9(3)
This OCCURS clause defines 24 three-position numeric fields.
Thus, TEMPERATURE is an array that refers to 72 positions or bytes of
storage.
Defining a Subscript
Collectively, these 24 fields within the array are called
TEMPERATURE, which is the identifier used to access them in the
the PROCEDURE DIVISION.
We use the identifier TEMPERATURE along with a subscript that
indicates which of the 24 fields we wish to access:
DISPLAY TEMPERATURE (23)
SUMMARY OF OCCURS
AND SUBSCRIPTS
1. An OCCURS clause is defined in the DATA
DIVISION to indicate the repeated occurrence of
items in an array that have the same format.
2. A subscript is used in the PROCEDURE DIVISION to
indicate which specific item within the array we
wish to access.
QUESTIONS?
SELF-TEST
Consider the following for Questions 1 through 5:
01 IN-REC.
05 AMT1
PIC 9(5).
05 AMT2
PIC 9(5).
05 AMT3
PIC 9(5).
05 AMT4
PIC 9(5).
05 AMT5
PIC 9(5).
SELF-TEST
1. An OCCURS clause could be used in place of
defining each AMT field separately because
____________________________________ .
SOLUTION: all AMTs have the same format or PIC
clause
SELF-TEST
2. (T or F) Suppose AMT2 and AMT4 had PIC 9(3). An
OCCURS clause could not be used to define all
the AMT fields.
SOLUTION: T
SELF-TEST
3. Recode the fields within IN-REC using an OCCURS
clause.
SOLUTION:
01 IN-REC.
05 AMT OCCURS 5 TIMES
PIC 9(5).
SELF-TEST
4. To access any of the five items defined with the
OCCURS clause, we must use a ____ in the
PROCEDURE DIVISION.
SOLUTION: subscript
SELF-TEST
5. Code a routine to determine the total of all five AMT fields.
Assume that a field called SUB has been defined in WORKINGSTORAGE to serve as a subscript.
SOLUTION: COBOL 85 (With an In-line PERFORM)
MOVE ZEROS TO TOTAL
PERFORM VARYING SUB FROM 1 BY 1 UNTIL SUB > 5
ADD AMT (SUB) TO TOTAL
END-PERFORM
...
Using an OCCURS in WORKINGSTORAGE for Storing Totals
We have seen that an OCCURS clause may be used as part of
an input record to indicate the repeated occurrence of
incoming fields.
Similarly, an OCCURS may be used as part of an output record to
define a series of fields.
An OCCURS clause may be used to define fields either in the FILE
SECTION or in WORKING-STORAGE.
Rules for Use of the
OCCURS Clause
Levels 02--49
An OCCURS clause may be used on levels 02-- 49
only.
That is, the OCCURS is not valid for the 01 level since
it must be used for defining fields, not records.
Elementary or Group Items may also be defined
with an OCCURS Clause.
Processing Data Stored
in an Array
Using OCCURS with VALUE
and REDEFINES Clauses
Sometimes we want to initialize elements in a
table or an array with specific values.
We have seen that with COBOL 85 you can use a
VALUE clause to set an entire array to zero:
01 ARRAY-1 VALUE ZERO.
05 TOTALS OCCURS 50 TIMES PIC 9(5).
Using an OCCURS Clause for
Table Handling
Defining a Table
A table is a list of stored fields that are looked up
or referenced by the program.
Tables are used in conjunction with table look-ups,
where a table look-up is a procedure that finds a
specific entry in the table.
Thus, an array stores data or totals to be
outputted, whereas a table is used for looking up
or referencing data.
Storing the Table in
WORKING-STORAGE
Storing data in a table file rather than in each transaction
record is more efficient because it minimizes data entry
operations.
It is also more efficient because the data can be more easily
maintained, or updated, in a separate table, as needed.
Any time input records need to be saved for future processing,
use a READINTO to store the data in WORKING-STORAGE.
Use of the SEARCH Statement for
Table and Array Processing
Format of the SEARCH
Statement
SEARCH identifier-1
[AT END imperative-statement-1]
WHEN condition-1 {imperativeSENTENCE} ...
statement-2} {NEXT
[END-SEARCH]*
*COBOL 85 only. If END-SEARCH is used, NEXT SENTENCE must be
replaced with CONTINUE unless your COBOL 85 compiler has an
enhancement that permits it.
Using the SEARCH ... AT END for
Data Validation
With the SEARCH statement, the AT END clause specifies what
should be done if the table has been completely searched and
no match is found.
Since it is possible for input errors to occur, we strongly
recommend that you always use this optional clause.
Without it, the ``no match'' condition would simply cause the
program to continue with the next sentence; thus producing
incorrect results or even a program interrupt.
The INDEXED BY Clause and
the SEARCH Statement
When using a SEARCH statement, table entries must be specified
with an index rather than a subscript.
An index is similar to a subscript, but it is defined along with the
table entries as part of the OCCURS description:
01 SALES-TAX-TABLE.
05 TABLE-ENTRIES OCCURS 1000 TIMES
INDEXED BY X1.
10 WS-ZIPCODE
PIC 9(5).
10 WS-TAX-RATE
PIC V999.
How an Index Differs From a Subscript
Indexes are processed differently and more efficiently than
subscripts.
When you define an index, the computer sets up an internal
storage area called an index register.
Registers use the displacement values determined by the index to
access table addresses.
This is faster than working with subscripts.
We recommend that you use indexes and SEARCH statements for
table look-ups.
How an Index Differs From a Subscript
Because an index refers to a displacement and not just an
occurrence value, its contents cannot be modified with a MOVE,
ADD, or SUBTRACT like a subscript can.
To change the contents of an index, then, we use either:
(1) a PERFORM ... VARYING, which can vary the values in either
subscripts or indexes.
(2) a SET statement, which can move, add, or subtract values in an
index.
Modifying the Contents of an
Index: The SET Statement
Basic Format:
SET index-name-1 {TO} {UP BY} {DOWN BY} integer-1
EXAMPLES:
Statement
Meaning
1. SET X1 TO 1
Move 1 to the X1 index.
2. SET X1 UP BY 1
Add 1 to the X1 index.
3. SET X1 DOWN BY 1 Subtract 1 from the X1 index.
Initializing an Index Before Using the
SEARCH
A SEARCH statement does not automatically initialize the
index at 1 because sometimes we may want to begin
searching a table at some point other than the beginning.
Initializing an index at 1 must be performed by a SET statement
prior to the SEARCH if we want to begin each table look-up with
the first entry; for example:
SET X1 TO 1
DIFFERENCES BETWEEN
SUBSCRIPTS AND INDEXES
Subscript represents an occurrence of an array or table element.
Defined in a separate WORKING-STORAGE entry.
To change a subscript's value, use a PERFORM ... VARYING or any
of the following:
MOVE 1 TO SUB
SUBTRACT 1 FROM SUB
ADD 1 TO SUB
DIFFERENCES BETWEEN
SUBSCRIPTS AND INDEXES
Index represents a displacement from the first address in the array or
table.
Defined along with the OCCURS for the array or table
To change an index value, use a PERFORM ... VARYING or any of
the following:
SET X1 TO 1
SET X1 DOWN BY 1
SET X1 UP BY 1
THE SEARCH ... VARYING OPTION FOR
PROCESSING PARALLEL TABLES
Format:
SEARCH identifier-1 VARYING
{identifier-2} {index-name-1}
[AT END imperative-statement-1]
{WHEN condition-1 {imperativestatement-2}{NEXT SENTENCE}
[END-SEARCH]*
*COBOL 85 only. The NEXT SENTENCE clause is not
permitted with the END-SEARCH unless your
compiler has an enhancement that allows it.
The SEARCH ALL Statement
Definition of a Serial
Search
1. The first entry in the table is searched.
2. If the condition is met, the table look-up is completed.
3. If the condition is not met, the index or subscript is incremented by
one, and the next entry is searched.
4. This procedure is continued until a match is found or the table has
been completely searched.
Definition of a Serial Search
A sequential or serial search, as described here, is best used
when either:
1. The entries in a table are not in either ascending or descending
sequence; that is, they are arranged randomly; or,
2. Table entries are organized so that the first values are the ones
encountered most frequently;
in this way, access time is minimized because you are apt to end the
search after the first few comparisons.
Definition of a Binary
Search
When table entries are arranged in sequence by
some field, such as T- CUSTOMER-NO, the most
efficient type of look-up is a binary search.
The following is the way the computer performs a
binary search:
Definition of a Binary Search
1. Begin by comparing CUST-NO of the input
customer record to the middle table argument
for T-CUSTOMER-NO.
For
example, this might be the twenty-fifth entry in
the table.
2. Since T-CUSTOMER-NOs are in sequence, if
CUST-NO-IN > T- CUSTOMER-NO (25) - which is
the middle entry in our table - this eliminates the
need for searching the first half of the table.
In
such a case, we compare CUST-NO-IN to TCUSTOMER-NO (37), the middle table argument of
the second half of the table (rounding down), and
continue our comparison in this way.
Definition of a Binary
Search
3. If CUST-NO-IN < T-CUSTOMER-NO (25), we compare CUST-NO-IN to
T-CUSTOMER-NO (12);
that is, we divide the top half of the table into two segments and
continue our comparison.
4. The binary search is complete either (a) when a match has been
found, that is, CUST-NO-IN = T-CUSTOMER-NO (X1), or (b) when
the table has been completely searched.
Uses of a Binary Search
1. When table entries are arranged in some sequence - either
ascending or descending.
2. When tables with a large number of sequential entries (e.g., 50 or
more) are to be looked up or searched.
For small tables or those in which entries are not arranged in a
sequence, the standard serial search look-up method previously
described is used.
Format for SEARCH ALL
SEARCH ALL identifier-1
[AT END imperative-statement-1]
WHEN {data-name-1 { IS EQUAL TO} {IS =}
{identifier-2} {literal-1} {arithmetic-expression-1}}
{condition-name-1
[AND {data-name-2 {IS EQUAL TO} {IS =}
{identifier-3}{literal-2}{arithmetic-expression-2}}]
{condition-name-2} . . .
{imperative-statement-2} {NEXT SENTENCE}
[END-SEARCH]* Cobol 85 only. NEXT SENTENCE cannot
typically be used with END-SEARCH.
Limitations of the SEARCH ALL
Statement
1. The condition following the word WHEN can test
only for equality:
Valid: WHEN T-CUSTOMER-NO (X1) = CUST-NO-IN
Invalid: WHEN T-WEIGHT-MAX (X1) < WEIGHTMAILED
Limitations of the SEARCH ALL
Statement
2. If the condition following the word WHEN is a compound
conditional:
a. Each part of the conditional can only consist of a relational test that
involves an equal condition.
b. The only compound condition permitted is with ANDs, not ORs.
Valid: WHEN S-AMT (X1) = AMT1 AND TAX-AMT (X1) = AMT2
Invalid: WHEN SALES-AMT (X1) = AMT3 OR AMT4 = AMT5
Limitations of the SEARCH
ALL Statement
3. Only one WHEN clause can be used with a SEARCH ALL.
4. The VARYING option may not be used with the SEARCH ALL.
5. The OCCURS item and its index, which define the table argument,
must appear to the left of the equal sign.
Valid: WHEN S-AMT (X1) = AMT1...
Invalid: WHEN AMT1 = S-AMT (X1)...
ASCENDING or DESCENDING KEY
with the SEARCH ALL Statement
1. To use the SEARCH ALL statement, we must indicate which table
entry will serve as the key field.
2. That is, we specify the table entry that will be in sequence so that
the binary search can be used to compare against that field.
3. We must indicate whether that KEY is ASCENDING or
DESCENDING.
ASCENDING or DESCENDING KEY
with the SEARCH ALL Statement
ASCENDING KEY - Entries are in sequence and increasing in value.
DESCENDING KEY - Entries are in sequence and decreasing in value.
Format:
(level-number 02--49) identifier-1
OCCURS integer-1 TIMES
{ASCENDING} {DESCENDING} KEY IS
data-name-2
INDEXED BY index-name-1
Differences Between the SEARCH
and the SEARCH ALL
SEARCH
Performs a serial search
Table entries need not be in any sequence
Requires a SET statement prior to the SEARCH to specify the starting
point for the look-up
Can include any relational test with the WHEN clause (<, >, =, <=, >=)
or any compound conditional
May include multiple WHEN clauses
Differences Between the SEARCH
and the SEARCH ALL
SEARCH ALL
Performs a binary search
Tables entries must be in sequence by the table argument or even
the table function. The field that is in sequence is specified in an
ASCENDING or DESCENDING KEY clause as part of the OCCURS entry
Does not need a SET prior to the SEARCH ALL
Can only have a single = condition tested with the WHEN clause
May only have one WHEN clause
MULTIPLE-LEVEL OCCURS
CLAUSE
When describing an area of storage, more than one level of
OCCURS may be used.
As many as seven levels of OCCURS are permitted with COBOL
85, and as many as three levels are permitted with COBOL 74.
Like a single-level OCCURS, multiple levels of OCCURS may be
used for:
(1) accumulating totals in an array.
(2) storing a table for ``look-up'' purposes.
RULES FOR USING A DOUBLE-LEVEL
OCCURS
1. If an item is defined by a double-level OCCURS clause, it must be
accessed by two subscripts.
2. The first subscript refers to the higher-level OCCURS; the second
subscript refers to the lower-level OCCURS.
3. The subscripts must be enclosed in parentheses.
RULES FOR USING A DOUBLE-LEVEL
OCCURS
4. Subscripts may consist of positive integers or data-names with
positive integer contents.
5. On most systems, the left parenthesis must be preceded by at
least one space; similarly, the right parenthesis must be followed
by a period, if it is the end of a sentence, or at least one space.
The first subscript within parentheses is followed by a comma and a
space.
Expanded Format for Accessing a
Double-Level or
Two-Dimensional Array
PERFORM [procedure-name-1 [{THROUGH} {THRU} procedurename-2]
[WITH TEST {BEFORE} {AFTER}]
VARYING {identifier-2} {index-name- 1} FROM
{identifier-3}{index-name-2} {literal-1}
BY {identifier-4} {literal-2}
UNTIL condition-1
[AFTER {identifier-5}{index-name-3}
FROM {identifier-6}{index-name-4} literal-3}
BY {identifier-7} {literal-4} UNTIL condition-2]
[END-PERFORM]*