The application will access the appropriate rate table indirectly. This feature of tableBASE is called Open Indirect (see Open Indirect).
Open Indirect causes a table to be searched for a target secondary table name. This secondary table is the one that will be opened if the search of the primary table is successful. The primary or first table may not be read password protected. The first table has only two fields:
TARGET-TABLE-NAME (8 bytes)
INDIRECT-OPEN-CRITERION (up to 50 bytes)
The second field is the key of the first table. For example, each key field might represent a date when the target rate table in TARGET-TABLE-NAME is to go into effect. The Set Indirect (SI) command is used to provide the processing date that becomes the search argument for the primary table. A search of the primary table is successful if the search argument is equal to a row-key, or is greater than one row-key, and less than the next row-key, of the primary table. After a successful Indirect Open operation, the target table name is placed in the TABLE field of the COMMAND-AREA, and the error code is 0. The FOUND code is N, whether the search was successful or not.
Abend processing will be suppressed in this example, so all calls to tableBASE must be followed by a test of the error code.
In COBOL
DATA DIVISION.
01 INPUT-RECORD.
05 .....
05 INPUT-PROCESSING-DATE PIC X(8).
05 INPUT-CODE .....
01 STATUS-SWITCHES.
05 ST-ABEND PIC X.
05 FILLER PIC X(7) VALUE SPACES.
01 RATE-ROW.
05 RATE-CODE.....
05 RATE-VALUE....
01 RATE-COMMAND-AREA.
05 RATE-COMMAND PIC XX VALUE SPACES.
05 RATE-TABLE PIC X(8) VALUE SPACES.
05 RATE-FOUND PIC X VALUE SPACES.
05 RATE-INDIRECT-IND PIC X VALUE LOW-VALUES.
05 RATE-RESERVED PIC X VALUE LOW-VALUES.
05 RATE-ABEND-OVERRIDE PIC X VALUE SPACES.
05 RATE-ERROR-CODE PIC S9(4) COMP VALUE +0.
05 RATE-COUNT PIC S9(9) COMP VALUE +0.
05 RATE-LOCK PIC X(8) VALUE SPACES.
05 RATE-LENGTHS.
10 RATE-ROW-OVERRIDE-LENGTH PIC S9(9) COMP VALUE +0.
10 RATE-ROW-ACTUAL-LENGTH PIC S9(9) COMP VALUE +0.
10 RATE-FG-KEY-LENGTH PIC S9(4) COMP VALUE +0.
05 RATE-FUNCTION-ID PIC S9(4) COMP VALUE +0.
05 RATE-FUNCTION-AREA.
10 RATE-DATE PIC X(8).
10 FILLER PIC X(20).
05 RATE-RETURNED-ABS-GEN-NO PIC S9(4) COMP VALUE +0.
05 RATE-ERROR-SUBCODE PIC S9(4) COMP VALUE +0.
***
* THE FOLLOWING IS A COPY OF CONTENTS OF PRIMARY RATETBL.
* IT IS PRESENTED HERE ONLY TO COMPLETE THE UNDERSTANDING
* OF TABLEBASE WHEN PROCESSING THE PRIMARY RATETBL.
***
01 RATETBL-PRIMARY-ROW.
05 RATETBL-SECONDARY PIC X(8) VALUE 'RATE2000'.
05 RATETBL-KEY PIC X(8) VALUE '20000101'.
PROCEDURE DIVISION.
HOUSE-KEEPING.
*** TURN OFF TABLEBASE ABEND FUNCTION.
MOVE 'N' TO ST-ABEND
MOVE 'CS' TO RATE-COMMAND
CALL 'TBLBASE' USING TB-PARM
RATE-COMMAND-AREA
STATUS-SWITCHES
*** GET TODAY'S DATE AND MOVE IT TO INPUT-PROCESSING-DATE
*** SET UP VALUE TO BE USED FOR INDIRECT TABLE OPEN
MOVE 'SI' TO RATE-COMMAND
CALL 'TBLBASE' USING TB-PARM
RATE-COMMAND-AREA
INPUT-PROCESSING-DATE
IF RATE-ERROR-CODE GREATER THAN ZERO
GO TO TABLEBASE-ERROR-RTN
END-IF
*** OPEN INDIRECT TABLE.
MOVE 'I' TO RATE-INDIRECT-IND
MOVE 'RATETBL' TO RATE-TABLE.
MOVE 'OR' TO RATE-COMMAND
***
* THE PRIMARY RATE IS SEARCHED USING TODAY'S DATE AS A KEY.
* SINCE IT IS GREATER THAN 20000101, THE ONLY ENTRY IN THE
* PRIMARY TABLE IS FOUND AND THE NAME 'RATE2000' IS PLACED
* IN THE RATE-COMMAND-AREA BY TABLEBASE AND IS OPENED READY FOR
* FURTHER PROCESSING.
***
CALL 'TBLBASE' USING TB-PARM
RATE-COMMAND-AREA
IF RATE-ERROR-CODE GREATER THAN ZERO
GO TO TABLEBASE-ERROR-RTN
ENDIF
GET-RECORD.
* (get input record)
PROCESS-ROW.
MOVE 'FK' TO RATE-COMMAND
CALL 'TBLBASE' USING TB-PARM
RATE-COMMAND-AREA
RATE-ROW
INPUT-CODE
IF RATE-ERROR-CODE GREATER THAN ZERO
GO TO TABLEBASE-ERROR-RTN
* (correct rate table for processing date will be used)
END-IF
In C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "dkh.h"
/*
* DK1TEX9C
*
* Access a Table Indirectly.
*
* The primary table contains the names of the secondary
* tables (to be open indirectly) and a key used to make
* the selection. A row of this primary table might be
* expressed with this C struct:
*
* typedef struct
* {
* char tblname_secondary [8];
* char selection_criteria [20];
* } PrimaryRow;
*
* The precise table that will be open indirectly is the
* one with the largest kyt equal to or less than the value
* specified in the selection_criteria field.
*/
/*
* Assume these are user inputs.
*/
static char szTableName[6] = "AARON";
static char szStatus[6] = "NYYYN";
static char szIndirectOpenCriterion[11] = "2003-04-21";
static char szReadPassword[2] = " ";
static int nGen = 0;
static int nRowSize = 20;
static int nKeySize = 5;
static int nKeyLocation = 1;
int main(void)
{
TbParmStruct tbParm;
TbCommandAreaStruct tbCommArea;
char sReadPassword[8];
char sStatus[8];
char sTableName[8];
char sIndirectOpenCriterion[50];
int nGeneration = nGen;
char * pRowArea = NULL;
/*
* Initialize the parameters.
*/
fixStringLength( szTableName, sTableName, 8 );
InitTbParm( &tbParm );
InitTbCommandArea( &tbCommArea, sTableName );
/*
* Initialize tableBASE with CS, ChangeStatus.
*/
fixStringLength( szStatus, sStatus, 8 );
memcpy( tbCommArea.tbCommand, "CS", 2 );
TBLBASE( &tbParm, &tbCommArea, sStatus );
if( tbCommArea.tbError != TB_SUCCESS )
{
printf( "CS\n");
printf( "Found code: %c\n", tbCommArea.tbFound );
printf( "Error code: %d\n", tbCommArea.tbError );
printf( "Sub code: %d\n", tbCommArea.tbErrorSubcode );
return tbCommArea.tbError;
}
/*
* Setup the indirect open with SI.
*/
fixStringLength( szIndirectOpenCriterion,
sIndirectOpenCriterion, 50 );
memcpy( tbCommArea.tbCommand, "SI", 2 );
TBLBASE( &tbParm, &tbCommArea, sIndirectOpenCriterion );
if( tbCommArea.tbError == TB_SUCCESS )
{
/*
* Open the indirect table (the tbCommArea.tbTable field
* was set to the primary table previously).
* If the key (selection criteria) is found (or the greatest key
* less than the criteria is found), the corresponding table
* will be open and the field tbCommArea.tbTable will be
* updated with the actual name of the open table.
*/
fixStringLength( szReadPassword, sReadPassword, 8 );
memcpy( tbCommArea.tbCommand, "OR", 2 );
tbCommArea.tbIndirectOpen = 'I';
TBLBASE( &tbParm, &tbCommArea, sReadPassword, nGeneration);
if( tbCommArea.tbError == TB_SUCCESS )
{
/*
* Get the first row (GF).
*/
pRowArea = (char *) malloc( nRowSize + 1 );
if( pRowArea == NULL )
return TB_ERROR;
memset( pRowArea, ' ', nRowSize );
fixStringLength( szReadPassword, sReadPassword, 8 );
memcpy( tbCommArea.tbCommand, "GF", 2 );
TBLBASE( &tbParm, &tbCommArea, pRowArea );
if( tbCommArea.tbError != TB_SUCCESS )
{
printf( "GF\n");
printf( "Found code: %c\n", tbCommArea.tbFound );
printf( "Error code: %d\n", tbCommArea.tbError );
printf( "Sub code: %d\n", tbCommArea.tbErrorSubcode );
free( pRowArea );
return tbCommArea.tbError;
}
/*
* Print the output.
*/
pRowArea[nRowSize] = '\0';
printf( "Row: %s\n", pRowArea );
/*
* Close the table (CL).
*/
memcpy( tbCommArea.tbCommand, "CL", 2 );
TBLBASE( &tbParm, &tbCommArea );
if( tbCommArea.tbError != TB_SUCCESS )
{
printf( "CL\n");
printf( "Found code: %c\n", tbCommArea.tbFound );
printf( "Error code: %d\n", tbCommArea.tbError );
printf( "Sub code: %d\n", tbCommArea.tbErrorSubcode );
return tbCommArea.tbError;
}
}
}
else
{
printf( "SI\n");
printf( "Found code: %c\n", tbCommArea.tbFound );
printf( "Error code: %d\n", tbCommArea.tbError );
printf( "Sub code: %d\n", tbCommArea.tbErrorSubcode );
return tbCommArea.tbError;
}
if( pRowArea != NULL )
free( pRowArea );
return TB_SUCCESS;
}