A part table is usually searched with a part number as the key. To enter order information when the part number is missing from the order, the part name may be used as an alternate key for searching the table.
PARTNO is a table on the tableBASE library and its key is Part Number. The PARTNO table is opened and an Alternate Index called PARTNAME is Invoked with the key of Part Name. This now allows access to either the PARTNAME table or the PARTNO table, two routes to the same data.
Note:
The Invoke Alternate (IA) command has been largely superseded by Open commands (OR and OW) that are capable of opening multiple Alternate Indexes for a single Data Table. However, the IA command remains the only way to generate a transient Alternate Index.
In COBOL
DATA DIVISION.
01 PART-ROW.
05 PART-NUMBER PIC X(10).
05 PART-NAME PIC X(25).
05 PART-FIELDS...
01 ORDER-PART-NAME PIC X(25) VALUE SPACES.
01 ORDER-PART-NUMBER PIC X(10) VALUE SPACES.
01 PARTNO-COMMAND-AREA.
05 PARTNO-COMMAND PIC XX VALUE SPACES.
05 PARTNO-TABLE PIC X(8) VALUE 'PARTNO'.
05 PARTNO-FOUND PIC X VALUE SPACES.
05 PARTNO-INDIRECT-IND PIC X VALUE LOW-VALUES.
05 PARTNO-RESERVED PIC X VALUE LOW-VALUES.
05 PARTNO-ABEND-OVERRIDE PIC X VALUE SPACES.
05 PARTNO-ERROR-CODE PIC S9(4) COMP VALUE +0.
05 PARTNO-COUNT PIC S9(9) COMP VALUE +0.
05 PARTNO-LOCK PIC X(8) VALUE SPACES.
05 PARTNO-LENGTHS.
10 PARTNO-ROW-OVERRIDE-LENGTH PIC S9(9) COMP VALUE +0.
10 PARTNO-ROW-ACTUAL-LENGTH PIC S9(9) COMP VALUE +0.
10 PARTNO-FG-KEY-LENGTH PIC S9(4) COMP VALUE +0.
05 PARTNO-FUNCTION-ID PIC S9(4) COMP VALUE +0.
05 PARTNO-FUNCTION-AREA PIC X(8) VALUE LOW-VALUES.
05 PARTNO-DATE-AREA REDEFINES PARTNO-FUNCTION-AREA.
10 PARTNO-DATE PIC X(8).
10 RESERVED PIC X(20).
05 PARTNO-RETURNED-ABS-GEN-NO PIC S9(4) COMP VALUE +0.
05 PARTNO-ERROR-SUBCODE PIC S9(4) COMP VALUE +0.
01 PARTNAME-COMMAND-AREA.
05 PARTNAME-COMMAND PIC XX VALUE SPACES.
05 PARTNAME-TABLE PIC X(8) VALUE 'PARTNAME'.
05 PARTNAME-FOUND PIC X VALUE SPACES.
05 PARTNAME-INDIRECT-IND PIC X VALUE LOW-VALUES.
05 PARTNAME-RESERVED PIC X VALUE LOW-VALUES.
05 PARTNAME-ABEND-OVERRIDE PIC X VALUE SPACES.
05 PARTNAME-ERROR-CODE PIC S9(4) COMP VALUE +0.
05 PARTNAME-COUNT PIC S9(9) COMP VALUE +0.
05 PARTNAME-LENGTHS.
10 PARTNAME-ROW-OVERRIDE-LENGTH PIC S9(9) COMP VALUE +0.
10 PARTNAME-ROW-ACTUAL-LENGTH PIC S9(9) COMP VALUE +0.
10 PARTNAME-FG-KEY-LENGTH PIC S9(4) COMP VALUE +0.
05 PARTNAME-FUNCTION-ID PIC S9(4) COMP VALUE +0.
05 PARTNAME-FUNCTION-AREA PIC X(8) VALUE LOW-VALUES.
05 PARTNAME-DATE-AREA REDEFINES PARTNAME-FUNCTION-AREA.
10 PARTNAME-DATE PIC X(8).
10 RESERVED PIC X(20).
05 PARTNAME-RETURNED-ABS-GEN-NO PIC S9(4) COMP VALUE +0.
05 PARTNAME-ERROR-SUBCODE PIC S9(4) COMP VALUE +0.
01 PARTNAME-ALT-DEFINITION.
05 PARTNAME-ORG PIC X VALUE 'S'.
05 PARTNAME-METHOD PIC X VALUE 'B'.
05 PARTNAME-KEY-COUNT PIC S9(4) COMP VALUE +1.
05 PARTNAME-KEY-LOCATION PIC S9(9) COMP VALUE +11.
05 PARTNAME-KEY-SIZE PIC S9(9) COMP VALUE +25.
PROCEDURE DIVISION.
HOUSE-KEEPING.
*** GET PARTNO TABLE FROM TABLE BASE LIBRARY.
MOVE 'OR' TO PARTNO-COMMAND
CALL 'TBLBASE' USING TB-PARM
PARTNO-COMMAND-AREA
*** INVOKE THE ALTERNATE INDEX. THIS CAUSES THE ALTERNATE
*** INDEX TO BE CREATED ON THE PARTNO TABLE.
MOVE 'IA' TO PARTNAME-COMMAND
CALL 'TBLBASE' USING TB-PARM
PARTNAME-COMMAND-AREA
PARTNO-TABLE
PARTNAME-ALT-DEFINITION
PROCESSING.
*** TO SEARCH FOR A VALID PARTNO WITH PART-NO AS A KEY, USE:
MOVE 'SK' TO PARTNO-COMMAND
CALL 'TBLBASE' USING TB-PARM
PARTNO-COMMAND-AREA
ORDER-PART-NUMBER
*** TO FETCH A PARTNO USING PART NAME AS A KEY INTO PARTNAME, USE:
MOVE 'FK' TO PARTNAME-COMMAND
CALL 'TBLBASE' USING TB-PARM
PARTNAME-COMMAND-AREA
PART-ROW
ORDER-PART-NAME
In C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "dkh.h"
/*
* DK1TEX6C
*
* Establish another key with which to search a table.
*/
/*
* Assume these are user inputs.
*/
static char szTableName[6] = "AARON";
static char szAltTableName[9] = "AARALT ";
static char szStatus[6] = "NYYYN";
static char szReadPassword[2] = " ";
static int nGen = 0;
static char szKey[6] = "TIGER";
static char szSecondKey[16] = "123456789012345";
static int nRowSize = 20;
static int nKeySize = 5;
static int nSecondKeySize = 15;
int main(void)
{
TbParmStruct tbParm;
TbCommandAreaStruct tbCommArea;
TbCommandAreaStruct tbCommArea1;
TbTableDefinitionStruct tbTableDef;
TbAltDefinitionStruct tbAltDef;
char sReadPassword[8];
char * pRowArea = NULL;
char * pKeyArea = NULL;
char * pSecondKeyArea = NULL;
char sStatus[8];
char sTableName[8];
int nGeneration = nGen;
/*
* Initialize the parameters.
*/
fixStringLength( szTableName, sTableName, 8 );
InitTbParm( &tbParm );
InitTbCommandArea( &tbCommArea, sTableName );
InitTbCommandArea( &tbCommArea1, sTableName );
InitTableDef( &tbTableDef );
InitAltDefinitionStruct( &tbAltDef );
/*
* 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;
}
tbAltDef.org = 'U';
tbAltDef.method = 'S';
tbAltDef.keyLocation = 6;
tbAltDef.keySize = 15;
/*
* Open the table for read with OR.
*/
fixStringLength( szReadPassword, sReadPassword, 8 );
memcpy( tbCommArea.tbCommand, "OR", 2 );
TBLBASE( &tbParm, &tbCommArea, sReadPassword, nGeneration);
if( tbCommArea.tbError != TB_SUCCESS )
{
printf( "OW\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;
}
/*
* Create a temporary Alternate Index with IA (InvokeAlternate).
* For performance reasons, it is better to use a different
* TbCommandAreaStruct for each table and for each index.
*/
fixStringLength( szAltTableName, tbCommArea1.tbTable, 8 );
memcpy( tbCommArea1.tbCommand, "IA", 2 );
TBLBASE( &tbParm, &tbCommArea1, sTableName, &tbAltDef );
if( tbCommArea1.tbError != TB_SUCCESS )
{
printf( "IA\n");
printf( "Found code: %c\n", tbCommArea1.tbFound );
printf( "Error code: %d\n", tbCommArea1.tbError );
printf( "Sub code: %d\n", tbCommArea1.tbErrorSubcode );
return tbCommArea1.tbError;
}
/*
* Allocate spaces for the keys and the row.
*/
pRowArea = (char *) malloc( nRowSize + 1 );
if( pRowArea == NULL )
return TB_ERROR;
memset( pRowArea, ' ', nRowSize );
pKeyArea = (char *) malloc( nKeySize );
if( pKeyArea == NULL )
{
free( pRowArea );
return TB_ERROR;
}
memset( pKeyArea, ' ', nKeySize );
pSecondKeyArea = (char *) malloc( nSecondKeySize );
if( pSecondKeyArea == NULL )
{
free( pRowArea );
free( pKeyArea );
return TB_ERROR;
}
memset( pSecondKeyArea, ' ', nSecondKeySize );
/*
* Search by Key (SK) using the Data Table.
*/
fixStringLength( szKey, pKeyArea, nKeySize );
memcpy( tbCommArea.tbCommand, "SK", 2 );
TBLBASE( &tbParm, &tbCommArea, pKeyArea );
if( tbCommArea.tbError != TB_SUCCESS || tbCommArea.tbFound != 'Y' )
{
printf( "SK\n");
printf( "Found code: %c\n", tbCommArea.tbFound );
printf( "Error code: %d\n", tbCommArea.tbError );
printf( "Sub code: %d\n", tbCommArea.tbErrorSubcode );
free( pRowArea );
free( pKeyArea );
free( pSecondKeyArea );
return tbCommArea.tbError;
}
else
{
printf( "Found code: %c\n", tbCommArea.tbFound );
}
/*
* Fetch by Key (FK) using the secondary index.
*/
fixStringLength( szSecondKey, pSecondKeyArea, nSecondKeySize );
memcpy( tbCommArea1.tbCommand, "FK", 2 );
/* Call TableBASE */
TBLBASE( &tbParm, &tbCommArea1, pRowArea, pSecondKeyArea );
if( tbCommArea1.tbError != TB_SUCCESS || tbCommArea1.tbFound != 'Y' )
{
printf( "FK\n");
printf( "Found code: %c\n", tbCommArea1.tbFound );
printf( "Error code: %d\n", tbCommArea1.tbError );
printf( "Sub code: %d\n", tbCommArea1.tbErrorSubcode );
free( pRowArea );
free( pKeyArea );
free( pSecondKeyArea );
return tbCommArea1.tbError;
}
else
{
pRowArea[nSecondKeySize] = '\0';
printf( "Row found by second key: %s\n", pRowArea );
}
if( pRowArea != NULL )
free( pRowArea );
if( pKeyArea != NULL )
free( pKeyArea );
if( pSecondKeyArea != NULL )
free( pSecondKeyArea );
return TB_SUCCESS;
}