Search a table to find the group of records that begin with the same truncated version of the table key. Change the table organization to sequential if presently random, user-ordered or hash; this is necessary because the command Fetch Generic (FG) operates only on sequentially organized tables. Access the table using a generic key by setting the low order part of key to the delimiter (usually an asterisk *). The first FG command will retrieve the first row in the group, and subsequent calls will retrieve the rest of the group. The user must test the found code after each call to make sure the group or table has not been exhausted. For more information see Fetch Generic (FG).
In COBOL
01 xxxx-SEARCH-KEY.
05 xxxx-SEARCH-KEY-1 PIC X(04) VALUE 'aaaa'.
05 xxxx-SEARCH-KEY-2 PIC X VALUE '*'.
05 xxxx-SEARCH-KEY-3 PIC X(04).
PROCEDURE DIVISION.
*** SETUP SEQUENTIAL/BINARY SEARCH.
*** CHANGE-ORG.
MOVE LOW-VALUES TO xxxx-DEFINITION-BLOCK
MOVE 'S' TO xxxx-ORG
MOVE 'B' TO xxxx-METHOD
MOVE 'CD' TO xxxx-COMMAND
CALL 'TBLBASE' USING TB-PARM
xxxx-COMMAND-AREA
xxxx-DEFINE
*** SET UP GENERIC KEY
MOVE PART-NO-1 TO xxxx-SEARCH-KEY-1
MOVE ZERO TO xxxx-COUNT
MOVE 'FG' TO xxxx-COMMAND
MOVE 'Y' TO xxxx-FOUND
PERFORM WHILE xxxx-FOUND = 'Y'
CALL 'TBLBASE' USING TB-PARM
xxxx-COMMAND-AREA
xxxx-ROW-AREA
xxxx-SEARCH-KEY
IF xxxx-FOUND = 'Y'
*** (process table row)
END-IF
END-PERFORM
In C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "dkh.h"
/*
* DK1TEX3C
*
* This program will fetch all rows which satisfy the generic
* search condition (in this case, that their key starts with
* the string "P").
*/
/*
* Assume these are user inputs.
*/
static char szTableName[6] = "AARON";
static char szStatus[6] = "NYYYN";
static char szWritePassword[2] = " ";
static char szSearchKey[2] = "P";
static int nGen = 0;
static int nKeyLength = 1;
int main(void)
{
TbParmStruct tbParm;
TbCommandAreaStruct tbCommArea;
TbTableDefinitionStruct tbTableDef;
char * pRowArea = NULL;
char * pSearchKey = NULL;
char sStatus[8];
char sTableName[8];
int nGeneration = nGen;
int notFound = 1;
/*
* Initialize the parameters.
*/
fixStringLength( szTableName, sTableName, 8 );
InitTbParm( &tbParm );
InitTbCommandArea( &tbCommArea, sTableName );
InitTableDef( &tbTableDef );
/*
* 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 Sequential/Binary Search with CD, ChangeDefinition.
*/
memcpy( tbCommArea.tbCommand, "CD", 2 );
tbTableDef.org = 'S';
tbTableDef.method = 'B';
TBLBASE( &tbParm, &tbCommArea, &tbTableDef, nGeneration );
if( tbCommArea.tbError != TB_SUCCESS )
{
printf( "CD\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;
}
/*
* GD, get table definition to retrieve the row length.
*/
memcpy( tbCommArea.tbCommand, "GD", 2 );
TBLBASE( &tbParm, &tbCommArea, &tbTableDef, nGeneration );
if( (tbCommArea.tbError != TB_SUCCESS)
|| (tbCommArea.tbFound == 'N') )
{
printf( "GD\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;
}
/*
* Allocate space for a row (with an additional string
* terminator) and for the key.
*/
pRowArea = (char *) malloc( tbTableDef.rowSize + 1 );
if( pRowArea == NULL )
return TB_ERROR;
memset( pRowArea, ' ', tbTableDef.rowSize);
pSearchKey = (char *) malloc( tbTableDef.keySize );
if( pSearchKey == NULL )
{
free( pRowArea );
return TB_ERROR;
}
memset( pSearchKey, ' ', tbTableDef.keySize );
/*
* Call tableBASE with FG, FetchGeneric.
*/
memcpy( tbCommArea.tbCommand, "FG", 2 );
tbCommArea.tbCount = 0;
tbCommArea.tbFgKeyLength = nKeyLength;
fixStringLength( szSearchKey, pSearchKey, tbTableDef.keySize );
while( notFound )
{
TBLBASE( &tbParm, &tbCommArea, pRowArea, pSearchKey );
if( tbCommArea.tbFound == 'Y' ) {
pRowArea[tbTableDef.rowSize] = '\0';
printf( "Found at Row %d: %s\n",
tbCommArea.tbCount, pRowArea );
notFound = 1;
}
else
{
notFound = 0;
}
}
/*
* Call tableBASE with CL, CloseTable.
*/
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 );
free( pRowArea );
free( pSearchKey );
return tbCommArea.tbError;
}
if( pRowArea != NULL )
free( pRowArea );
if( pSearchKey != NULL )
free( pSearchKey );
return TB_SUCCESS;
}