2-Dimension Tables in COBOL
Sometimes the data that we need does not lend itself to a simple one dimension table - we need
two dimensions. For example, reading distances on a map require that we know where we are
starting and where we are going.
In the example to illustrate 2-Dimensional tables, assume that we want to know the fares from
Boston to Chicago, Atlanta, and Austin for both tourist and first class. If all we wanted to
know was the fares to the three destinations, a one dimensional table would work. But, when the
extra dimension of knowing the fare for both tourist and first class is included, we will need a
two dimension table. For our example we will assume that Chicago has a code of 1, Atlanta has a
code of 2 and Austin has a code of 3. We will also assume that tourist has a code of 1 and
first class has a code of two.
|
Tourist (1) |
First Class (2) |
Chicago (1) |
349.79 |
499.50 |
Atlanta (2) |
150.00 |
299.95 |
Austin (3) |
389.00 |
550.00 |
The data on the input record has a code for destination and a code for class. The legal codes
in the destination field are 1, 2, and 3 to stand for the three destinations and the legal codes
in the class field are 1 and 2 to stand for the two classes.
01 INPUT-REC.
...
05 CLASSZ PIC 9.
05 DESTINATIONZ PIC 9.
The table would be setup in WORKING-STORAGE in the following way:
01 RATE-TABLE.
05 TOURIST.
10 T-CHICAGO PIC 999V99 VALUE 349.79.
10 T-ATLANTA PIC 999V99 VALUE 150.00.
10 T-AUSTIN PIC 999V99 VALUE 389.00.
05 FIRST-CLASS.
10 F-CHICAGO PIC 999V99 VALUE 499.50.
10 F-ATLANTA PIC 999V99 VALUE 299.95.
10 F-AUSTIN PIC 999V99 VALUE 550.00.
01 RDF-RATE-TABLE REDEFINES RATE-TABLE.
05 CLASS-GROUP OCCURS 2 TIMES.
10 RATE PIC 999V99 OCCURS 3 TIMES.
Note that the names used on the 05 and for that matter on the 10 level are not
required, I could have used FILLER or no data name. The names are their for clarification and
are in fact a wise programming move because they will also clarify the table for anyone looking
at the program.
When the programmer sets up a two dimension table, one of the dimensions is picked to describe
first. In this example, class was chosen. This means that in defining the table, each of the
two classes has its own 05 level. In this example they are called 05 TOURIST and
05 FIRST-CLASS. Each of these 05 levels will be broken down as the second dimension is defined
on the 10 level. (Remember the rule that PIC is only used on the lowest level, so because the
05 is being broken down there are no pictures on the 05 level.) Since there are three
destinations in both classes, each of the 05 levels has three 10 levels beneath it, one for each
destination. For example, under the 05 TOURIST, there are 10 T-CHICAGO, 10 T-ATLANTA, and
10 T-AUSTIN. Each of these is given a PIC and a VALUE.
In the redefinitions, this structure is continued. The 05 CLASS-GROUP OCCURS 2 TIMES because in
the original layout there were two 05s. Each of these 05s now has another name CLASS-GROUP.
Beneath each of the 05s there were three 10 level elements so beneath 05 CLASS-GROUP we see the
10 level RATE which OCCURS 3 TIMES and has a PIC corresponding to the 10 level pictures in the
original data layout.
It is important to see the connection between the 05s in the original data layout and the 05 in
the redefinition and the 10s in the original data layout and the 10s in the redefination because
it helps to clarify the table layout. (Note that there are other ways to layout this table that
would also work, but would sacrifice this clean connection.)
To use the RATE from the table, we must use the CLASSZ code and the DESTINATIONZ code as
SUBSCRIPTs to point to the correct RATE. As you can see, there will be two SUBSCRIPTs, one for
each dimension of the table. Since the first breakdown in the table (the 05 level) is for class,
the SUBSCRIPT to select the correct class is the first subscript needed. If CLASSZ contains a 1,
the CLASSZ subscript will point to the first 05 level (05 TOURIST) and if CLASSZ contains a 2,
the CLASSZ subscript will point to the second 05 level (05 FIRST-CLASS). Now that the correct
05 level has been pointed to, the correct destination within that class is needed. For this,
the DESTINATIONZ subscript is used to point to the correct 10 level. It is critical that the
subscripts be used in the correct order - the first one points to the correct 05 level and the
second one points to the correct 10 level.
If the goal is to move RATE to a field on the printline, then the MOVE statement to accomplish
all this is:
MOVE RATE (CLASSZ, DESTINATIONZ) TO RATE-PR.
Analyzing the move:
- If CLASSZ is 2 and DESTINATIONZ is 3 (first class to AUSTIN), then the subscripts will point
to the second 05 level and the third 10 level, so the rate of 550.00 will be moved to the output.
- If CLASSZ is 1 and DESTINATIONZ is 2 (tourist to ATLANTA), then the subscripts will point to
the first 05 level and the second 10 level, so the rate of 150.00 will be moved to the output.
- If CLASSZ is 2 and DESTINATIONZ is 1, (first class to CHICAGO), then the subscripts will
point to the second 05 level and the first 10 level, so the rate 499.50 will be moved to the
output.
In the example presented here, the decision was made to break the table down by class and
destination within class. An alternative approach would have been to break the table down by
destination and then class within destination.
01 RATE-TABLE.
05 CHICAGO.
10 CH-TOURIST PIC 999V99 VALUE 349.79.
10 CH-FIRSTCL PIC 999V99 VALUE 499.50.
05 ATLANTA.
10 AT-TOURIST PIC 999V99 VALUE 150.00
10 AT-FIRSTCL PIC 999V99 VALUE 299.95.
05 AUSTIN.
10 AU-TOURIST PIC 999V99 VALUE 389.00.
10 AU-FIRSTCL PIC 999V99 VALUE 550.00.
01 RDF-RATE-TABLE REDEFINES RATE-TABLE.
05 DESTINATION-GROUP OCCURS 3 TIMES.
10 RATE PIC 999V99 OCCURS 2 TIMES.
In this table, the programmer decided to put destination at the 05 level and break each
destination down into class. Since the first breakdown in the table (at the 05 level) is for
destination, the DESTINATIONZ subscript is the first subscript or pointer that is used. If the
DESTINATIONZ subscript is 1, the subscript will point to the first 05 level which is CHICAGO, 2
will point to ATLANTA, and 3 will point to AUSTIN. Once the pointer has selected the
appropriate 05, the CLASSZ subscript can be used to select the correct class within that
destination. Assuming the goal is to move the RATE to a field on the printline called RATE-PR,
the MOVE statement will be:
MOVE RATE (DESTINATIONZ, CLASSZ) TO RATE-PR.
Analyzing the move:
- If DESTINATIONZ is 3 and CLASSZ is 2 (AUSTIN flying first class), then the subscripts will
point to the third 05 level and the second 10 level, so the rate of 550.00 will be moved to the
output.
- If DESTINATIONZ is 2 and CLASSZ is 1(ATLANTA flying tourist), then the subscripts will
point to the second 05 level and the first 10 level, so the rate of 150.00 will be moved to the
output.
- If DESTINATIONZ is 1 and CLASSZ is 2, (CHICAGO flying first class), then the subscripts
will point to the first 05 level and the second 10 level, so the rate 499.50 will be moved to
the output.
3-Dimension Tables in COBOL
Complex data sometimes requires sophistocated tables with multiple levels of dimensions within
the table. Prior to COBOL 85, the three dimenision tables were the limit. COBOL 85 allows up to
7 dimensions of subscripting, we will stop with three!
Three dimension tables allow the user to access a table based on three subscripts and therefore
makes a more complex table. This is an example of a three dimension table that could be used to
establish phone rates. The calls are being originated from Boston and are being placed at a
particular time of day, using either station to station or person to person, to a particular
city.
|
Day (1) |
Evening (2) |
Night (3) |
TO |
Sta-to-Sta |
Pers-to-Pers |
Sta-to-Sta |
Pers-to-Pers |
Sta-to-Sta |
Pers-to-Pers |
Fall River (1) |
1.20 |
1.35 |
1.00 |
1.15 |
.85 |
1.00 |
New Bedford (2) |
1.25 |
1.40 |
1.05 |
1.20 |
.90 |
1.05 |
Newport (3) |
1.35 |
1.50 |
1.15 |
1.30 |
1.00 |
1.15 |
Providence(4) |
1.40 |
1.55 |
1.20 |
1.35 |
1.05 |
1.20 |
The table could have been set up with any field chosen to be the major category and others the
subcategories. This example uses time of day and then type of call within time of day and
finally city being called within type of call. There is nothing special about this selection,
it was totally arbitrary.
01 THREE-DIM-TABLE.
05 DAY-RATES.
10 DAY-S-S.
15 TO-FR PIC 9V99 VALUE 1.20.
15 TO-NB PIC 9V99 VALUE 1.25.
15 TO-NP PIC 9V99 VALUE 1.35.
15 TO-PR PIC 9V99 VALUE 1.40.
10 DAY-P-P.
15 TO-FR PIC 9V99 VALUE 1.35.
15 TO-NB PIC 9V99 VALUE 1.40.
15 TO-NP PIC 9V99 VALUE 1.50.
15 TO-PR PIC 9V99 VALUE 1.55.
05 EVENING-RATES.
10 EVENING-S-S.
15 TO-FR PIC 9V99 VALUE 1.00.
15 TO-NB PIC 9V99 VALUE 1.05.
15 TO-NP PIC 9V99 VALUE 1.15.
15 TO-PR PIC 9V99 VALUE 1.20.
10 EVENING-P-P.
15 TO-FR PIC 9V99 VALUE 1.15.
15 TO-NB PIC 9V99 VALUE 1.20.
15 TO-NP PIC 9V99 VALUE 1.30.
15 TO-PR PIC 9V99 VALUE 1.35.
05 NIGHT-RATES.
10 NIGHT-S-S.
15 TO-FR PIC 9V99 VALUE 0.85.
15 TO-NB PIC 9V99 VALUE 0.90.
15 TO-NP PIC 9V99 VALUE 1.00.
15 TO-PR PIC 9V99 VALUE 1.05.
10 NIGHT-P-P.
15 TO-FR PIC 9V99 VALUE 1.00.
15 TO-NB PIC 9V99 VALUE 1.05.
15 TO-NP PIC 9V99 VALUE 1.15.
15 TO-PR PIC 9V99 VALUE 1.20.
01 RDF-THREE-DIM-TABLE REDEFINES THREE-DIM-TABLE.
05 TIME-PERIODS OCCURS 3 TIMES.
10 TYPE-CALLS OCCURS 2 TIMES.
15 RATE PIC 9V99 OCCURS 4 TIMES.
To use this table, there must be subscripts that tell the time of day, the type of call, and the
destination city. The codes on the input that will be used as the subscripts are:
01 INPUT-RECORDS
05 ...
05 TIME-CODE PIC 9.
05 TYPE-CODE PIC 9.
05 PLACE-CODE PIC 9.
Since the time of day is described on the 05 level, the first subscript must point to the
correct 05 level for time of day. This means that TIME-CODE is the first subscript. Then the
10 level has entries for station to station and person to person, so the second subscript must
point to the correct type. This means TYPE-CODE is the second subscript. Finally the 10 level
is broken down into destinations that are shown on the 15 level. The third subscript must point
to the correct 15 level. This means PLACE-CODE is the third subscript. If the table had been
broken down differently, then the subscripting of the move statement would change to correspond.
Assuming the goal is to move the RATE to a field on the printline, the MOVE statement would be:
MOVE RATE (TIME-CODE, TYPE-CODE, PLACE-CODE) TO RATE-PR.