DSN8DLTC
Compares the data in the EMP_PHOTO_RESUME sample Db2 table to the data in the source data sets to ensure that the LOB columns are being populated and retrieved correctly.
/*********************************************************************
* Module name = DSN8DLTC (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Validate length and contents of sample LOB data *
* *
* *
* Licensed Materials - Property of IBM *
* 5635-DB2 *
* (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved. *
* *
* STATUS = Version 9 *
* *
* Function: Compares the data in the EMP_PHOTO_RESUME sample DB2 *
* table to the data in the source data sets to ensure that *
* the LOB columns are being populated and retrieved *
* correctly. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: CEESTART (Language Environment entry point) *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters *
* *
* Input: Symbolic label/name = PSEGINnn, where 00 <= nn <= 99 *
* Description = PSEG photo image data *
* *
* Symbolic label/name = BMPINnn, where 00 <= nn <= 99 *
* Description = BMP photo image data *
* *
* Symbolic label/name = RESUMEnn, where 00 <= nn <= 99 *
* Description = Resume data *
* *
* Output: Symbolic label/name = SYSPRINT *
* Description = Report and messages *
* *
* Normal Exit: Return Code = 0000 *
* - Message: DSN8DLTC DB2 Sample Program *
* Results of LOB data validation *
* for employee number xxxxxx *
* follow: *
* *
* - Message: *** VALID: The PSEG BLOB column length *
* matches the PSEG file length *
* length *
* - Message: *** VALID: The PSEG BLOB column data *
* matches the PSEG file data *
* *
* - Message: *** VALID: The BMP BLOB column length *
* matches the BMP file length *
* length *
* *
* - Message: *** VALID: The BMP BLOB column data *
* matches the BMP file data *
* *
* - Message: *** VALID: The RESUME CLOB column length *
* matches the RESUME file length *
* length *
* *
* - Message: *** VALID: The RESUME CLOB column data *
* matches the RESUME file data *
* *
* Error Exit: Return Code = 0008 *
* - Message: *** ERROR: The PSEG BLOB column data does *
* does not match the PSEG file *
* data *
* - first mismatch occurred at *
* byte offset nnn *
* *
* - Message: *** ERROR: The PSEG BLOB column length *
* does not match the PSEG file *
* length *
* - PSEG BLOB length is: nnnn *
* - PSEG file length is: nnnn *
* *
* - Message: *** ERROR: The BMP BLOB column data does *
* does not match the BMP file *
* data *
* - first mismatch occurred at *
* byte offset nnn *
* *
* - Message: *** ERROR: The BMP BLOB column length *
* does not match the BMP file *
* length *
* - BMP BLOB length is: nnnn *
* - BMP file length is: nnnn *
* *
* - Message: *** ERROR: The RESUME CLOB column data does*
* does not match the RESUME file *
* data *
* - first mismatch occurred at *
* byte offset nnn *
* *
* - Message: *** ERROR: The RESUME BLOB column length *
* does not match the RESUME file *
* length *
* - RESUME BLOB length is: nnnn *
* - RESUME file length is: nnnn *
* *
* - Message: *** ERROR: DSN8DLTC DB2 Sample Program *
* Unable to open BMPINnn DD data *
* set. Processing terminated. *
* *
* - Message: *** ERROR: DSN8DLTC DB2 Sample Program *
* Unable to open RESUMEnn DD data *
* set. Processing terminated. *
* *
* - Message: *** ERROR: DSN8DLTC DB2 Sample Program *
* Unexpected SQLCODE encountered *
* at location xxx *
* Error detailed below *
* Processing terminated *
* (DSNTIAR-formatted message *
* follows). *
* *
* External References: *
* - Routines/Services: DSNTIAR *
* - Data areas : DSNTIAR error_message *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8DLTC: *
* - Set DD counter (nn) to 00 *
* - Do while more PSEGINnn DD's to process *
* - Call getPSEGdata to read in an employee's photo image in PSEG*
* PSEG format from the data set associated with the PSEGINnn *
* DD. *
* - Call getBMPdata to read in an employee's photo image in BMP *
* format from the data set associated with the BMPINnn DD. *
* - Call storeBLOBdata to apply the PSEG and BMP images to the *
* PSEG_PHOTO and BMP_PHOTO columns of the EMP_PHOTO_RESUME *
* sample table. *
* - Increment DD counter (nn) by 1. *
* End DSN8DLTC *
* *
* getPSEGdata: *
* - Open the PSEGINnn input file *
* - Read in bytes and concatenate them in a buffer until EOF *
* - Close the PSEGINnn input file *
* *
* getBMPdata: *
* - Open the BMPINnn input file *
* - Read in bytes and concatenate them in a buffer until EOF *
* - Close the BMPINnn input file *
* *
* storeBLOBdata: *
* - Extract the employee serial from bytes 10-15 of the PSEG *
* buffer. *
* - SQL UPDATE the PSEG buffer into the PSEG_PHOTO column and the *
* BMP buffer into the BMP_PHOTO column of the EMP_PHOTO_RESUME *
* sample table for the employee number. *
* - If an SQL error occurs, call sql_error *
* *
* sql_error: *
* - call DSNTIAR to format the unexpected SQLCODE. *
* *
*********************************************************************/
/********************** C library definitions ***********************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/***************************** Equates ******************************/
#define NO 0 /* False */
#define YES 1 /* True */
#define NOT_OK 0 /* Bad */
#define OK 1 /* Good */
#define TIAR_DIM 10 /* Max no. of DSNTIAR msgs */
#define TIAR_LEN 80 /* Length of DSNTIAR messages */
/****************************** Files *******************************/
FILE *BMPin; /* pointer to BMP input file */
FILE *PSEGin; /* pointer to PSEG input file */
FILE *RESUMEin; /* pntr to resume input file */
/************************** Global Storage **************************/
int status = OK; /* Run status indicator */
int mismatch = NO; /* Data check status */
short int DDcounter = 0; /* DD allocation counter */
short int validDD = YES; /* unprocessed DD indicator */
short int PSEGblkLen = 0; /* length of PSEG input block */
short int PSEGblkPos = 0; /* offset in PSEG input block */
short int PSEGrecLen = 0; /* length of PSEG input record*/
short int PSEGrecPos = 0; /* offset in PSEG input record*/
short int BMPblkLen = 0; /* length of BMP input block */
short int BMPblkPos = 0; /* offset in BMP input block */
short int BMPrecLen = 0; /* length of BMP input record */
short int BMPrecPos = 0; /* offset in BMP input record */
short int RSMblkLen = 0; /* length of resume inp block */
short int RSMblkPos = 0; /* offset in resume inp block */
short int RSMrecLen = 0; /* length of resume inp record*/
short int RSMrecPos = 0; /* offset in resume inp record*/
int byteIn; /* current incoming byte */
/******************** DB2 SQL Communication Area ********************/
EXEC SQL INCLUDE SQLCA;
/**************************** DB2 Tables ****************************/
EXEC SQL DECLARE EMP_PHOTO_RESUME TABLE
( EMPNO CHAR(06) NOT NULL,
EMP_ROWID ROWID,
PSEG_PHOTO BLOB( 500K ),
BMP_PHOTO BLOB( 100K ),
RESUME CLOB( 5K ) );
/************** DB2 Host and Null Indicator Variables ***************/
EXEC SQL BEGIN DECLARE SECTION;
char hvEMPNO[7]; /* Hots var for emp no. col */
SQL TYPE IS BLOB(500K) PSEGinRec; /* Area for PSEG input record */
SQL TYPE IS BLOB(500K) hvPSEG_PHOTO;/* Host var for PSEG photo col*/
short int niPSEG_PHOTO = 0; /* Null ind for PSEG photo col*/
SQL TYPE IS BLOB(100K) BMPinRec; /* Area for BMP input record */
SQL TYPE IS BLOB(100K) hvBMP_PHOTO; /* Host var for BMP photo col */
short int niBMP_PHOTO = 0; /* Null ind for BMP photo col */
SQL TYPE IS CLOB(5K) RESUMErec; /* Area for RESUME input rec */
SQL TYPE IS CLOB(5K) hvRESUME; /* Host var for resume column */
short int niRESUME = 0; /* Null ind for resume column */
EXEC SQL END DECLARE SECTION;
/********************** DB2 Message Formatter ***********************/
struct error_struct { /* DSNTIAR message structure */
short int error_len;
char error_text[TIAR_DIM][TIAR_LEN];
} error_message = {TIAR_DIM * (TIAR_LEN)};
#pragma linkage( dsntiar, OS )
extern short int dsntiar( struct sqlca *sqlca,
struct error_struct *msg,
int *len );
/************************* Global Functions *************************/
int main( void ); /* driver */
void readPSEGfile( void ); /* load data from PSEG file */
void readBMPfile( void ); /* load data from BMP file */
void readResumeFile( void ); /* load data from resume file */
void readEMP_PHOTO_RESUMEtable(void); /* get PSEG, BMP, and resume */
void compareData( void ); /* compare DB2 data vs. file */
void sql_error( char *locnMsg ); /* generate msg for SQL error */
/********************************************************************/
/*************************** main routine ***************************/
/********************************************************************/
int main( void )
{
/*******************************************************************
* Write identification header *
*******************************************************************/
printf( "****************************************"
"****************************************\n" );
printf( "* DSN8DLTC DB2 Sample Program\n" );
printf( "****************************************"
"****************************************\n" );
/*******************************************************************
* Cycle through PSEGINnn and BMPINnn DD pairs, incrementing the DD *
* counter, until all pairs have been processed. *
*******************************************************************/
for( DDcounter=0; validDD == YES && status == OK; DDcounter++ )
{
/***************************************************************
* Fetch the PSEG data from the PSEGINnn data set. This record *
* also contains the serial number of the employee associated *
* with the photo. *
***************************************************************/
readPSEGfile();
/***************************************************************
* Fetch the BMP data from the BMPINnn data set *
***************************************************************/
if( validDD == YES && status == OK )
readBMPfile();
/***************************************************************
* Fetch the resume data from the RESUMEin data set *
***************************************************************/
if( validDD == YES && status == OK )
readResumeFile();
/***************************************************************
* Fetch the BMP and PSEG photo image and resume data from DB2 *
***************************************************************/
if( validDD == YES && status == OK )
readEMP_PHOTO_RESUMEtable();
/***************************************************************
* Compare the data on DB2 to the data from the flatfiles *
***************************************************************/
if( validDD == YES && status == OK )
compareData();
} /* end for */
/*******************************************************************
* If an unexpected situation occurred, set return code 0012 *
*******************************************************************/
if( status != OK )
return( 12 );
/*******************************************************************
* Or, if a data mismatch was detected, set return code 0008 *
*******************************************************************/
else if( mismatch == YES )
return( 8 );
/*******************************************************************
* Otherwise, set return code 0000 *
*******************************************************************/
else
return( 0 );
} /* end main */
void readPSEGfile( void )
/*********************************************************************
* Called by the main routine to read the contents of the PSEG input *
* data set into a buffer, PSEGinRec. Subsequently, this buffer will *
* be compared to the data in the PSEG_PHOTO column of the EMP_PHOTO_ *
* RESUME table to ensure a match. *
**********************************************************************
* Because the C language is not record-oriented in the sense of MVS *
* data sets, it's necessary to treat the PSEG data set, which has a *
* variable-blocked format, as an unformatted dataset in order to *
* access the block descriptor word (BDW) of each input block and the *
* record descriptor word (RDW) of each input record. *
* *
* Each RDW provides the number of bytes of data in its record, *
* including 4 bytes for itself. *
* *
* Each BDW provides the number of bytes of data in its block, *
* including 4 bytes for each RDW in the block and 4 bytes for *
* itself. *
*********************************************************************/
{
/*******************************************************************
* local variables *
*******************************************************************/
char PSEGinDD[12] = "DD:PSEGIN\0"; /* PSEGin DD template */
char DDnum[2]; /* DD number string template */
/*******************************************************************
* intialize work variables *
*******************************************************************/
PSEGrecLen = 0;
PSEGrecPos = 0;
PSEGblkPos = 0;
PSEGblkLen = 0;
PSEGinRec.length = 0;
/*******************************************************************
* form the DD name for the next PSEG data set *
*******************************************************************/
sprintf( DDnum,"%02d",DDcounter ); /* convert DD cntr to string */
strcat( PSEGinDD,DDnum ); /* form PSEGINnn DD name */
/*******************************************************************
* open the PSEG input file *
*******************************************************************/
PSEGin = fopen( PSEGinDD,"rb,recfm=u" );
if( PSEGin == NULL ) /* if no pointer returned */
validDD = NO; /* .. no more data sets left */
/*******************************************************************
* read the 1st byte of the record *
*******************************************************************/
while( status == OK
&& validDD == YES
&& (byteIn = getc(PSEGin)) != EOF )
{
/***************************************************************
* if at the end of a block, read and process the next BDW *
***************************************************************/
if( PSEGblkPos >= PSEGblkLen && PSEGrecPos >= PSEGrecLen )
{
/***********************************************************
* length of block = (16**2) * BDW[0] *
* ............... + (16**0) * BDW[1] *
* ............... - 4 (length of BDW) *
***********************************************************/
PSEGblkLen = 256 * byteIn;
byteIn = getc(PSEGin);
PSEGblkLen = PSEGblkLen + byteIn - 4;
/***********************************************************
* skip remainder of BDW *
***********************************************************/
byteIn = getc(PSEGin);
byteIn = getc(PSEGin);
PSEGblkPos = 0;
/***********************************************************
* read first byte of RDW *
***********************************************************/
byteIn = getc(PSEGin);
}
/***************************************************************
* if at the end of a record, read and process next RDW *
***************************************************************/
if( PSEGrecPos >= PSEGrecLen )
{
/***********************************************************
* length of record = (16**2) * RDW[0] *
* ................ + (16**0) * RDW[1] *
* ................ - 4 (length of RDW) *
***********************************************************/
PSEGrecLen = 256 * byteIn;
byteIn = getc(PSEGin);
PSEGrecLen = PSEGrecLen + byteIn - 4;
/***********************************************************
* skip remainder of RDW *
***********************************************************/
byteIn = getc(PSEGin);
byteIn = getc(PSEGin);
PSEGrecPos = 0;
/***********************************************************
* update position in block *
***********************************************************/
PSEGblkPos = PSEGblkPos + PSEGrecLen + 4;
}
/***************************************************************
* move PSEG data bytes to the PSEGin file buffer *
***************************************************************/
else
{
PSEGinRec.data[PSEGinRec.length++] = byteIn;
PSEGrecPos++;
}
}
/*******************************************************************
* close the PSEG input file *
*******************************************************************/
fclose( PSEGin );
} /* end readPSEGfile */
void readBMPfile( void )
/*********************************************************************
* Called by the main routine to read the contents of the BMP input *
* data set into a buffer, BMPinRec. Subsequently, this buffer will *
* be compared to the data in the BMP_PHOTO column of the EMP_PHOTO_ *
* RESUME table to ensure a match. *
**********************************************************************
* Because the C language is not record-oriented in the sense of MVS *
* data sets, it's necessary to treat the BMP data set, which has a *
* variable-blocked format, as an unformatted dataset in order to *
* access the block descriptor word (BDW) of each input block and the *
* record descriptor word (RDW) of each input record. *
* *
* Each RDW provides the number of bytes of data in its record, *
* including 4 bytes for itself. *
* *
* Each BDW provides the number of bytes of data in its block, *
* including 4 bytes for each RDW in the block and 4 bytes for *
* itself. *
*********************************************************************/
{
/*******************************************************************
* local variables *
*******************************************************************/
char BMPinDD[12] = "DD:BMPIN\0"; /* BMPin DD template */
char DDnum[2]; /* DD number string template */
/*******************************************************************
* intialize work variables *
*******************************************************************/
BMPrecLen = 0;
BMPrecPos = 0;
BMPblkPos = 0;
BMPblkLen = 0;
BMPinRec.length = 0;
/*******************************************************************
* form the DD name for the next BMP data set *
*******************************************************************/
sprintf( DDnum,"%02d",DDcounter ); /* convert DD cntr to string */
strcat( BMPinDD,DDnum ); /* form BMPINnn DD name */
/*******************************************************************
* open the current BMPINnn DD data set *
*******************************************************************/
BMPin = fopen( BMPinDD,"rb,recfm=u" );
if( BMPin == NULL )
{
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLTC DB2 Sample Program\n" );
printf( "*** Unable to open BMPIN%s DD data set\n",
DDnum );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
status = NOT_OK;
}
/*******************************************************************
* read the 1st byte of the record *
*******************************************************************/
while( status == OK && (byteIn = getc(BMPin)) != EOF )
{
/***************************************************************
* if at the end of a block, read and process the next BDW *
***************************************************************/
if( BMPblkPos >= BMPblkLen && BMPrecPos >= BMPrecLen )
{
/***********************************************************
* length of block = (16**2) * BDW[0] *
* ............... + (16**0) * BDW[1] *
* ............... - 4 (length of BDW) *
***********************************************************/
BMPblkLen = 256 * byteIn;
byteIn = getc(BMPin);
BMPblkLen = BMPblkLen + byteIn - 4;
/***********************************************************
* skip remainder of BDW *
***********************************************************/
byteIn = getc(BMPin);
byteIn = getc(BMPin);
BMPblkPos = 0;
/***********************************************************
* read first byte of RDW *
***********************************************************/
byteIn = getc(BMPin);
}
/***************************************************************
* if at the end of a record, read and process next RDW *
***************************************************************/
if( BMPrecPos >= BMPrecLen )
{
/***********************************************************
* length of record = (16**2) * RDW[0] *
* ................ + (16**0) * RDW[1] *
* ................ - 4 (length of RDW) *
***********************************************************/
BMPrecLen = 256 * byteIn;
byteIn = getc(BMPin);
BMPrecLen = BMPrecLen + byteIn - 4;
/***********************************************************
* skip remainder of RDW *
***********************************************************/
byteIn = getc(BMPin);
byteIn = getc(BMPin);
BMPrecPos = 0;
/***********************************************************
* update position in block *
***********************************************************/
BMPblkPos = BMPblkPos + BMPrecLen + 4;
}
/***************************************************************
* move BMP data bytes to the BMPin file buffer *
***************************************************************/
else
{
BMPinRec.data[BMPinRec.length++] = byteIn;
BMPrecPos++;
}
}
/*******************************************************************
* close the BMP input file *
*******************************************************************/
fclose( BMPin );
} /* end readBMPfile */
void readResumeFile( void )
/*********************************************************************
* Called by the main routine to read the contents of the RESUME in- *
* put data set into a buffer, RESUMErec. Subsequently, this buffer *
* will be compared to the data in the RESUME column of the EMP_ *
* PHOTO_RESUME table to ensure a match. *
**********************************************************************
* Because the C language is not record-oriented in the sense of MVS *
* data sets, it's necessary to treat the RESUME data set, which has *
* a variable-blocked format, as an unformatted dataset in order to *
* access the block descriptor word (BDW) of each input block and the *
* record descriptor word (RDW) of each input record. *
* *
* Each RDW provides the number of bytes of data in its record, *
* including 4 bytes for itself. *
* *
* Each BDW provides the number of bytes of data in its block, *
* including 4 bytes for each RDW in the block and 4 bytes for *
* itself. *
*********************************************************************/
{
/*******************************************************************
* local variables *
*******************************************************************/
char RESUMEDD[12] = "DD:RESUME\0"; /* BMPin DD template */
char DDnum[2]; /* DD number string template */
/*******************************************************************
* intialize work variables *
*******************************************************************/
RSMrecLen = 0;
RSMrecPos = 0;
RSMblkPos = 0;
RSMblkLen = 0;
RESUMErec.length = 0;
/*******************************************************************
* form the DD name for the next RESUME data set *
*******************************************************************/
sprintf( DDnum,"%02d",DDcounter ); /* convert DD cntr to string */
strcat( RESUMEDD,DDnum ); /* form RESUMEnn DD name */
/*******************************************************************
* open the current RESUMEnn DD data set *
*******************************************************************/
RESUMEin = fopen( RESUMEDD,"rb,recfm=u" );
if( RESUMEin == NULL )
{
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLTC DB2 Sample Program\n" );
printf( "*** Unable to open RESUME%s DD data set\n",
DDnum );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
status = NOT_OK;
}
/*******************************************************************
* read the 1st byte of the record *
*******************************************************************/
while( status == OK && (byteIn = getc(RESUMEin)) != EOF )
{
/***************************************************************
* if at the end of a block, read and process the next BDW *
***************************************************************/
if(RSMblkPos >= RSMblkLen && RSMrecPos >= RSMrecLen)
{
/***********************************************************
* length of block = (16**2) * BDW[0] *
* ............... + (16**0) * BDW[1] *
* ............... - 4 (length of BDW) *
***********************************************************/
RSMblkLen = 256 * byteIn;
byteIn = getc(RESUMEin);
RSMblkLen = RSMblkLen + byteIn - 4;
/***********************************************************
* skip remainder of BDW *
***********************************************************/
byteIn = getc(RESUMEin);
byteIn = getc(RESUMEin);
RSMblkPos = 0;
/***********************************************************
* read first byte of RDW *
***********************************************************/
byteIn = getc(RESUMEin);
}
/***************************************************************
* if at the end of a record, read and process next RDW *
***************************************************************/
if( RSMrecPos >= RSMrecLen )
{
/***********************************************************
* length of record = (16**2) * RDW[0] *
* ................ + (16**0) * RDW[1] *
* ................ - 4 (length of RDW) *
***********************************************************/
RSMrecLen = 256 * byteIn;
byteIn = getc(RESUMEin);
RSMrecLen = RSMrecLen + byteIn - 4;
/***********************************************************
* skip remainder of RDW *
***********************************************************/
byteIn = getc(RESUMEin);
byteIn = getc(RESUMEin);
RSMrecPos = 0;
/***********************************************************
* update position in block *
***********************************************************/
RSMblkPos = RSMblkPos + RSMrecLen + 4;
}
/***************************************************************
* move RESUME data bytes to the RESUMEin file buffer *
***************************************************************/
else
{
RESUMErec.data[RESUMErec.length++] = byteIn;
RSMrecPos++;
}
}
/*******************************************************************
* close the RESUME input file *
*******************************************************************/
fclose( RESUMEin );
} /* end readResumeFile */
void readEMP_PHOTO_RESUMEtable( void )
/*********************************************************************
* Called by the main routine to retrieve the PSEG and BMP photo *
* images and the resume data for an employee from the EMP_PHOTO_ *
* RESUME table. *
* *
* The employee number, which is the table key, is extracted from *
* bytes 10-15 of the PSEG input record. *
*********************************************************************/
{
/*******************************************************************
* local variables *
*******************************************************************/
char *pEmpno; /* Pointer to employee no. */
/*******************************************************************
* Extract the employee number from bytes 10-15 of the PSEG record *
*******************************************************************/
pEmpno = &PSEGinRec.data[9]; /* point to start of emp. no. */
strncpy( hvEMPNO,pEmpno,6 ); /* and capture it */
/*******************************************************************
* Fetch the PSEG, BMP, and resume data for the employee *
*******************************************************************/
EXEC SQL SELECT PSEG_PHOTO, BMP_PHOTO, RESUME
INTO :hvPSEG_PHOTO,
:hvBMP_PHOTO,
:hvRESUME
FROM EMP_PHOTO_RESUME
WHERE EMPNO = :hvEMPNO;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "readEMP_PHOTO_RESUMEtable @1" );
}
} /* end readEMP_PHOTO_RESUMEtable */
void compareData( void )
/*********************************************************************
* Called by the main routine to compare the data from the photo *
* images and the resume data for an employee from the EMP_PHOTO_ *
* RESUME table. *
* *
* The employee number, which is the table key, is extracted from *
* bytes 10-15 of the PSEG input record. *
*********************************************************************/
{
unsigned long h;
/*******************************************************************
* Write heading for current employee *
*******************************************************************/
printf( "* Results of LOB data validation for employee "
"number %s follow:\n", hvEMPNO );
printf( "* \n" );
/*******************************************************************
* Compare employee's PSEG photo image on DB2 to flatfile version *
*******************************************************************/
if( PSEGinRec.length == hvPSEG_PHOTO.length )
{
printf( "* VALID: The PSEG BLOB column length "
"matches the PSEG file length\n" );
for( h = 0;
h < PSEGinRec.length
&& PSEGinRec.data[h] == hvPSEG_PHOTO.data[h];
h++ );
if( h == PSEGinRec.length )
printf( "* VALID: The PSEG BLOB column data "
"matches the PSEG file data\n" );
else
{
printf( "* > ERROR: The PSEG BLOB column data "
"does not match the PSEG file data\n" );
printf( "* - first mismatch occurred "
"at byte offset %d\n",h );
mismatch = YES;
}
}
else
{
printf( "* > ERROR: The PSEG BLOB column length "
"does not match the PSEG file length\n" );
printf( "* - PSEG BLOB length is: %d\n",hvPSEG_PHOTO.length );
printf( "* - PSEG file length is: %d\n",PSEGinRec.length );
mismatch = YES;
}
/*******************************************************************
* Compare employee's BMP photo image on DB2 to flatfile version *
*******************************************************************/
if( BMPinRec.length == hvBMP_PHOTO.length )
{
printf( "* VALID: The BMP BLOB column length "
"matches the BMP file length\n" );
for( h = 0;
h < BMPinRec.length
&& BMPinRec.data[h] == hvBMP_PHOTO.data[h];
h++ );
if( h == BMPinRec.length )
printf( "* VALID: The BMP BLOB column data "
"matches the BMP file data\n" );
else
{
printf( "* > ERROR: The BMP BLOB column data "
"does not match the BMP file data\n" );
printf( "* - first mismatch occurred "
"at byte offset %d\n",h );
mismatch = YES;
}
}
else
{
printf( "* > ERROR: The BMP BLOB column length "
"does not match the BMP file length\n" );
printf( "* - BMP BLOB length is: %d\n",hvBMP_PHOTO.length );
printf( "* - BMP file length is: %d\n",BMPinRec.length );
mismatch = YES;
}
/*******************************************************************
* Compare employee's resume image on DB2 to flatfile version *
*******************************************************************/
if( RESUMErec.length == hvRESUME.length )
{
printf( "* VALID: The RESUME CLOB column length "
"matches the resume file length\n" );
for( h = 0;
h < RESUMErec.length
&& RESUMErec.data[h] == hvRESUME.data[h];
h++ );
if( h == RESUMErec.length )
printf( "* VALID: The RESUME CLOB column data "
"matches the resume file data\n" );
else
{
printf( "* > ERROR: The RESUME CLOB column data "
"does not match the resume file data\n" );
printf( "* - first mismatch occurred "
"at byte offset %d\n",h );
mismatch = YES;
}
}
else
{
printf( "* > ERROR: The RESUME CLOB column length "
"does not match the resume file length\n" );
printf( "* - RESUME CLOB length is: %d\n",hvRESUME.length );
printf( "* - Resume file length is: %d\n",RESUMErec.length );
mismatch = YES;
}
printf( "****************************************"
"****************************************\n" );
} /* end compareData */
void sql_error( char *locmsg )
/*********************************************************************
* SQL error handler *
*********************************************************************/
{
short int rc; /* DSNTIAR Return code */
int j,k; /* Loop control */
static int lrecl = TIAR_LEN; /* Width of message lines */
/*******************************************************************
* print the location message *
*******************************************************************/
printf( "*****************************************************\n" );
printf( "*** ERROR: DSN8DLTC DB2 Sample Program\n" );
printf( "*** Unexpected SQLCODE encountered at location\n" );
printf( "*** %.68s\n", locmsg );
printf( "*** Error detailed below\n" );
printf( "*** Processing terminated\n" );
printf( "*****************************************************\n" );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<TIAR_DIM; j++ )
{
for( k=0; k<TIAR_LEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end sql_error */