Você está na página 1de 56

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]*

Você também pode gostar