DSN8ED4
Demonstrates how to use an application program to call DSNTPSMP, the Db2 SQL Procedures Processor.
/********************************************************************* 00010000
* Module name = DSN8ED4 (sample program) * 00020000
* * 00030000
* DESCRIPTIVE NAME: Sample client for: * 00040000
* DSNTPSMP (DB2 SQL Procedures Processor) * 00050000
* * 00060000
* LICENSED MATERIALS - PROPERTY OF IBM * 00070000
* 5625-DB2 * 00080000
* (C) COPYRIGHT 1982, 2003 IBM CORP. ALL RIGHTS RESERVED. * 00090000
* * 00100000
* STATUS = VERSION 8 * 00110000
* * 00120000
* Function: Demonstrates how to use an application program to call * 00130000
* DSNTPSMP, the DB2 SQL Procedures Processor. DSN8ED4 * 00140000
* collects and passes user-provided SQL Procedure source * 00150000
* code and prep options to DSNTPSMP, and outputs the * 00160000
* report(s), if any, returned from DSNTPSMP by result set. * 00170000
* * 00180000
* Notes: * 00190000
* Dependencies: Requires SYSPROC.DSNTPSMP * 00200000
* * 00210000
* Restrictions: * 00220000
* * 00230000
* Module type: C program * 00240000
* Processor: DB2 Precompiler * 00250000
* IBM C/C++ for OS/390 V1R3 or higher * 00260000
* Module size: See linkedit output * 00270000
* Attributes: Reentrant and reusable * 00280000
* * 00290000
* Entry point: DSN8ED4 * 00300000
* Purpose: See Function * 00310000
* Linkage: Standard MVS program invocation, three parameters. * 00320000
* * 00330000
* Parameters: DSN8ED4 uses the C "main" argument convention of * 00340000
* argv (argument vector) and argc (argument count). * 00350000
* * 00360000
* - ARGV[0]: (input) pointer to a char[9], * 00370000
* null-terminated string having the name of * 00380000
* this program (DSN8ED4) * 00390000
* - ARGV[1]: (input) pointer to a char[21], * 00400000
* null-terminated string having the action * 00410000
* that DSNTPSMP is to perform: * 00420000
* - BUILD: Prepare a new SQL Procedure * 00430000
* - REBUILD: Prepare an existing SQL * 00440000
* - QUERYLEVEL: Verify DSNTPSMP level @05* 00450004
* - DESTROY: Remove an SQL Procedure * 00460000
* - REBIND: Rebind the package of an exist- * 00470000
* ing SQL Procedure * 00480000
* - ARGV[2]: (input) pointer to a char[262], * 00490000
* null-terminated string having the schema * 00500000
* and name of the SQL Procedure to be * 00510000
* processed by DSNTPSMP (e.g. DSN8.DSN8ES2) * 00520000
* - ARGV[3]: (input) pointer to a char[9], * 00530000
* null-terminated string having the author- * 00540000
* ization id to be used for BUILDOWNER and * 00550003
* for calling DSNTPSMP. * 00560003
* - ARGV[4]: (input) pointer to a char[17], * 00570000
* null-terminated string having the name of * 00580000
* the server where DSNTPSMP is to be run. * 00590000
* This is an optional parameter; the local * 00600000
* server is used if no argument is provided. * 00610000
* * 00620000
* Inputs: DSN8ED4 allocates these input DDs: * 00630000
* - PCOPTS : Options for the DB2 precompiler * 00640000
* - COPTS : Options for the C compiler * 00650000
* - PLKDOPTS: Options for the pre-link editor * 00660000
* - LKEDOPTS: Options for the link editor * 00670000
* - BINDOPTS: Options for the DB2 BIND * 00680000
* - SQLIN : Source code for the SQL Procedure * 00690000
* * 00700000
* Outputs: DSN8ED4 allocates these output DD * 00710000
* - REPORT01: First report data set from DSNTPSMP * 00720000
* - REPORT02: Second report data set from DSNTPSMP * 00730000
* - REPORT03: Third report data set from DSNTPSMP * 00740000
* * 00750000
* Normal Exit: Return Code: 0000 * 00760000
* - Message: DSNTPSMP has completed with return code 0 * 00770000
* - Message: SQL changes have been committed @04* 00780000
* * 00790000
* Normal with Warnings Exit: Return Code: 0004 +@04* 00800000
* - Message: DSNTPSMP has completed with return code 4 * 00810000
* - Message: SQL changes have been committed -@04* 00820000
* * 00830000
* Error Exit: Return Code: 0012 * 00840000
* - Message: DSNTPSMP has completed with return code <n>* 00850000
* - Message: The length of the argument specified for * 00860000
* the <parameter-name> does not fall within * 00870000
* the required bounds of <minimum-length> * 00880000
* and <maximum-length> * 00890000
* - Message: The argument specified for the action * 00900000
* parameter is invalid * 00910000
* - Message: Invalid sequence number <sequence-number> * 00920000
* specified for REPORTnn DD * 00930000
* - Message: DSN8ED4 was invoked with <parameter-count> * 00940000
* parameters. At least 3 parameters are * 00950000
* required * 00960000
* - Message: Unable to open <DD-name> * 00970000
* - Message: Unable to close <DD-name> * 00980000
* - Message: <formatted SQL text from DSNTIAR> * 00990000
* - Message: SQL changes have been rolled back @04* 01000000
* * 01010000
* External References: * 01020000
* - Routines/Services: DSNTIAR: DB2 msg text formatter * 01030000
* - Data areas : None * 01040000
* - Control blocks : None * 01050000
* * 01060000
* * 01070000
* Pseudocode: * 01080000
* DSN8ED4: * 01090000
* - call getCallParms to receive and validate call parm arguments* 01100000
* - case action * 01110000
* - when BUILD, call getReBuildData * 01120000
* - when DESTROY, call getDestroyData * 01130000
* - when REBUILD, call getReBuildData * 01140000
* - when REBIND, call getRebindData * 01150000
* - when QUERYLEVEL, call getLevelData * 01160003
* - otherwise call issueInvalidActionError * 01170000
* - call connectToLocation * 01180000
* - call setAuthID to set the current authorization id @pq53353 * 01190003
* - call callDSNTPSMP to invoke the DB2 SQL Procedures Processor * 01200000
* - call processDSNTPSMPresultSet to write reports from DSNTPSMP * 01210000
* - If no errors, call processSqlCommit to commit work @04 * 01220000
* Else call processSqlRollback to undo work @04 * 01230000
* End DSN8ED4 * 01240000
* * 01250000
* * 01260000
* Change activity = * 01270000
* PQ46962 03/28/2001 changed line feed character to hex 25 @01 * 01280000
* PQ43444 04/12/2001 Disable LEOPTS DD (LE options are not @02 * 01290000
* processed by DSNTPSMP). Remission the @02 * 01300000
* leOptions hostvar as alterStmt. @02 * 01310000
* PQ56601 03/06/2002 Trim +/- continuation characters from @03 * 01320000
* BIND options to prevent BIND errors. @03 * 01330000
* These characters are often used to con- @03 * 01340000
* tinue BIND statements being processed @03 * 01350000
* by the DB2 DSN command processor (which @03 * 01360000
* uses TSO i/o services that recognize @03 * 01370000
* them as continuation characters) but @03 * 01380000
* they are not otherwise valid in DB2 @03 * 01390000
* commands. @03 * 01400000
* PQ61782 07/16/2002 Distinguish between DSNTPSMP return code @04 * 01410000
* and DSN8ED4 return code; Issue SQL COMMIT@04 * 01420000
* when DSNTPSMP returns rc = 0 or rc = 4; @04 * 01430000
* Otherwise issue SQL ROLLBACK @04 * 01440000
* D55199 12/08/2003 Adjust to use DSNTPSMP 1.2x interface @05 * 01450004
* D56462 02/12/2004 Allocate maximum of 6 output reports @06 * 01460005
*********************************************************************/ 01470000
01480000
/********************** C library definitions ***********************/ 01490000
#include <errno.h> 01500000
#include <stdio.h> 01510000
#include <stdlib.h> 01520000
#include <string.h> 01530000
01540000
/**************************** Constants *****************************/ 01550000
#define NULLCHAR '\0' /* Null character */ 01560000
#define RETNRM 0 /* Normal return code @04*/ 01570000
#define RETWRN 4 /* Warning return code */ 01580000
#define RETERR 8 /* Error return code */ 01590000
#define RETSEV 12 /* Severe error return code */ 01600000
#define INTERFACE "1.2" /* DSNTPSMP innterface level */ 01610003
01620000
enum flag {No, Yes}; /* Settings for flags */ 01630000
01640000
01650000
/***************** Input: SQL Procedure Source Code *****************/ 01660000
FILE *sqlInFile; /* Pointer to SQL source DD */ 01670000
01680000
01690000
/*********** Output: DB2 SQL Procedures Processor Reports ***********/ 01700000
FILE *reportDD; /* Pointer to curr report DD */ 01710000
char reportDDName[12]; /* For generated DD name */ 01720000
unsigned short reportLRECL; /* length req'd for output rec*/ 01730000
01740000
01750000
/************************ Working variables *************************/ 01760000
unsigned short resultSetReturned = 0;/* DSNTPSMP result set stat@04*/ 01770000
long int DSNTPSMP_rc = -1; /* DSNTPSMP return code @04*/ 01780000
long int rc = 0; /* program return code */ 01790000
char levelquery ='N'; /* Is this a level check? @05*/ 01800004
01810000
01820000
/******************** DB2 SQL Communication Area ********************/ 01830000
EXEC SQL INCLUDE SQLCA; 01840000
01850000
01860000
/************************ DB2 Host Variables ************************/ 01870000
EXEC SQL BEGIN DECLARE SECTION; 01880000
01890000
char authID[9]; /* Authorization id-BUILDOWNER*/ 01900000
01910000
char locationName[17]; /* Server location name */ 01920000
01930000
char action[21]; /* Command for PSM processor */ 01940000
char routineName[262]; /* SQL Procedure schema.name */ 01950000
SQL TYPE IS CLOB(2M) sqlSource; /* SQL Procedure source @05*/ 01960004
01970000
char precompOptions[256];/* precompiler options */ 01980000
char compileOptions[256];/* compilation parameters */ 01990000
char prelinkOptions[256];/* prelink options */ 02000000
char linkOptions[256]; /* link-edit options */ 02010000
char bindOptions[1025]; /* DB2 bind options */ 02020000
char alterStmt[32672]; /* ALTER PROC text @02*/ 02030000
02040000
char sqlSourceDsn[81]; /* Source data set name */ 02050000
char outputString[256]; /* DSNTPSMP status area */ 02060000
02070000
char DSNTPSMP_pname[19] /* DSNTPSMP procedure-name */ 02080000
= "SYSPROC.DSNTPSMP\0"; 02090000
02100000
char stepName[17]; /* DSNTPSMP stepname */ 02110000
char fileName[9]; /* DSNTPSMP output DD name */ 02120000
long int reportLineNumber; /* DSNTPSMP report line no. */ 02130000
char reportLine[256]; /* DSNTPSMP report line */ 02140000
02150000
EXEC SQL END DECLARE SECTION; 02160000
02170000
02180000
/*************** DB2 Result Set Locator Host Variables **************/ 02190000
EXEC SQL BEGIN DECLARE SECTION; 02200000
static volatile SQL TYPE IS RESULT_SET_LOCATOR *DSNTPSMP_rs_loc1; 02210000
EXEC SQL END DECLARE SECTION; 02220000
02230000
02240000
/********************** DSN8ED4 Function Models *********************/ 02250000
int main /* DSN8ED4 driver */ 02260000
( int argc, /* - Input argument count */ 02270000
char *argv[] /* - Input argument vector */ 02280000
); 02290000
void getCallParms /* Process args to call parms */ 02300000
( int argc, /* - Input argument count */ 02310000
char *argv[] /* - Input argument vector */ 02320000
); 02330000
void getReBuildData( void ); /* Get SQL Proc re/build data */ 02340000
void getDestroyData( void ); /* Get SQL Proc destroy data */ 02350000
void getRebindData( void ); /* Get SQL Proc rebind data */ 02360000
void getLevelData( void ); /* Get DSNTPSMP level data */ 02370003
void getOptions /* Read specified options file*/ 02380000
( char *options, /* -out: list of options read */ 02390000
int maxBytes, /* - in: max size of list */ 02400000
char *optionsDDname /* - in: name of DD to read */ 02410000
); 02420000
void getSqlSource( void ); /* Read SQL Procedure Source */ 02430000
void setAuthID( void ); /* Set the current DB2 auth id*/ 02440003
void connectToLocation( void ); /* Connect to DB2 location */ 02450000
void callDSNTPSMP( void ); /* Run SQL Procedure Processor*/ 02460000
void listDSNTPSMPcallParms( void ); /* List parms sent to DSNTPSMP*/ 02470000
void processDSNTPSMPresultSet( void );/* Process DSNTPSMP rslt sets */ 02480000
void associateResultSetLocator(void); /* Assoc DSNTPSMP RS locator */ 02490000
void allocateResultSetCursor( void ); /* Alloc DSNTPSMP RS cursor */ 02500000
void writeDSNTPSMPreports( void ); /* Output a DSNTPSMP report */ 02510000
void fetchFromResultSetCursor( void );/* Read DSNTSPMP RS cursor */ 02520000
void openReportDataSet /* Alloc DD for a report */ 02530000
( short int reportNumber /* - in: Seqeunce number */ 02540000
); 02550000
void closeReportDataSet( void ); /* Dealloc DD for a report */ 02560000
void trimTrailingBlanks /* Strip off trailing blanks */ 02570000
( char *string /* - in: string to be trimmed */ 02580000
); 02590000
void stripContinuationCharacter /* Strip off trailing - or + */ 02600000
( char *string /* - in: string to be trimmed */ 02610000
); /*@03*/ 02620000
void processSqlCommit( void ); /* Commit SQL changes @04*/ 02630000
void processSqlRollback( void ); /* Rollback SQL changes @04*/ 02640000
void issueDataSetClosingError /* Handler for ds close error */ 02650000
( char *DDname, /* - in: name of errant DD */ 02660000
int LEerrno /* - in: LE diagnostic errno */ 02670000
); 02680000
void issueDataSetOpeningError /* Handler for ds open error */ 02690000
( char *DDname, /* - in: name of errant DD */ 02700000
int LEerrno /* - in: LE diagnostic errno */ 02710000
); 02720000
void issueDataSetReadingError /* Handler for ds read error */ 02730000
( char *DDname, /* - in: name of errant DD */ 02740000
int LEerrno /* - in: LE diagnostic errno */ 02750000
); 02760000
void issueInvalidCallParmCountError /* Handler for parm count err */ 02770000
( int argc /* - in: no. parms received */ 02780000
); 02790000
void issueInvalidActionError /* Handler for unknown action */ 02800000
( char *action /* - in: action specified */ 02810000
); 02820000
void issueInvalidLevelError /* Handler for wrong DSNTPSMP */ 02830003
( char *level /* - in: level encountered */ 02840003
); 02850003
void issueInvalidDDnumError /* Handler for unknown DD seq */ 02860000
( short invalidDDnum /* - in: invalid DD sequ. no. */ 02870000
); 02880000
void issueInvalidParmLengthError /* Handler for parm len error */ 02890000
( char *parmName, /* - in: identify of parm */ 02900000
int minLength, /* - in: min valid length */ 02910000
int maxLength /* - in: max valid length */ 02920000
); 02930000
void issueSqlError /* Handler for SQL error */ 02940000
( char *locMsg /* - in: Call location */ 02950000
); 02960000
02970000
02980000
int main /* DSN8ED4 driver */ 02990000
( int argc, /* - Input argument count */ 03000000
char *argv[] /* - Input argument vector */ 03010000
) 03020000
/******************************************************************* 03030000
* Main Driver: * 03040000
* - Gets arguments for call parms * 03050000
* - Gets processing options and data * 03060000
* - Connects to remote location, if one was specified * 03070000
* - Calls the DB2 SQL Procedure Processor, DSNTSPMP * 03080000
* - Processes any result set(s) returned from DSNTPSMP * 03090000
* * 03100000
*******************************************************************/ 03110000
{ /***************************************************************** 03120000
* Extract the following information from the call parms: * 03130000
* (1) DB2 location name where where SQL Procedure is to be built,* 03140000
* destroyed, rebuilt, rebound, etc.) * 03150000
* (2) DB2 SQL Procedure Processor action (Build,Destroy,...) * 03160000
* (3) Name of SQL Procedure to be built, destroyed, rebound, etc.* 03170000
*****************************************************************/ 03180000
getCallParms( argc,argv ); 03190000
03200000
/***************************************************************** 03210000
* Collect DSNTPSMP parms appropriate for the user-passed action * 03220000
*****************************************************************/ 03230000
if( rc < RETSEV ) 03240000
{ if( memcmp( action,"BUILD",5 ) == 0 ) 03250000
{ getReBuildData(); 03260000
} 03270000
else if( memcmp( action,"DESTROY",7 ) == 0 ) 03280000
{ getDestroyData(); 03290000
} 03300000
else if( memcmp( action,"REBUILD",7 ) == 0 ) 03310000
{ getReBuildData(); 03320000
} 03330000
else if( memcmp( action,"REBIND",6 ) == 0 ) 03340000
{ getRebindData(); 03350000
} 03360000
else if( memcmp( action,"QUERYLEVEL",10 ) == 0 ) 03370003
{ getLevelData(); 03380003
levelquery='Y'; 03390003
} 03400003
else 03410000
{ issueInvalidActionError( action ); 03420000
} 03430000
} 03440000
03450000
/***************************************************************** 03460000
* Connect to location where the SQL Procedure is to be processed * 03470000
*****************************************************************/ 03480000
if( rc < RETSEV && strlen(locationName) > 0 ) 03490000
connectToLocation(); 03500000
03510003
/***************************************************************** 03520003
* Set current DB2 authorization id to use when calling DSNTPSMP * 03530003
*****************************************************************/ 03540003
if( rc < RETSEV ) /*@pq53353*/ 03550003
setAuthID(); 03560003
03570000
/***************************************************************** 03580000
* Call the PSM processor * 03590000
*****************************************************************/ 03600000
if( rc < RETSEV ) 03610000
callDSNTPSMP(); 03620000
03630000
/***************************************************************** 03640000
* Process the result set, if any, from DSNTPSMP * 03650000
*****************************************************************/ 03660000
if( resultSetReturned ) /*@04*/ 03670000
processDSNTPSMPresultSet(); 03680000
03690000
/***********************************************************+@04** 03700000
* If DSNTPSMP returns either 0 (normal) or 4 (warnings), commit * 03710000
* the SQL changes; Otherwise, rollback the SQL changes * 03720000
*****************************************************************/ 03730000
if( DSNTPSMP_rc == RETNRM || DSNTPSMP_rc == RETWRN ) 03740000
{ processSqlCommit(); 03750000
if( rc < DSNTPSMP_rc ) 03760000
rc = DSNTPSMP_rc; 03770000
} 03780000
else 03790000
{ processSqlRollback(); 03800000
if( rc < RETSEV ) 03810000
rc = RETSEV; 03820000
} /*-@04*/ 03830000
03840000
/***************************************************************** 03850000
* Return highest completion code * 03860000
*****************************************************************/ 03870000
return( rc ); 03880000
03890000
} /* end of main */ 03900000
03910000
03920000
void getCallParms /* Process args to call parms */ 03930000
( int argc, /* - Input argument count */ 03940000
char *argv[] /* - Input argument vector */ 03950000
) 03960000
/******************************************************************* 03970000
* Verifies that correct call parms have been passed in: * 03980000
* - Three parameters (action, routine name, and authorization id) * 03990000
* require arguments * 04000000
* - The fourth parameter (location name) is optional * 04010000
*******************************************************************/ 04020000
{ if( argc < 4 || argc > 5 ) 04030000
{ issueInvalidCallParmCountError( argc ); 04040000
} 04050000
else if( strlen( argv[1] ) < 1 || strlen( argv[1] ) > 20 ) 04060000
{ issueInvalidParmLengthError("DSNTPSMP Action",1,20); 04070000
} 04080000
else if( strlen( argv[2] ) < 1 || strlen( argv[2] ) > 261 ) 04090000
{ issueInvalidParmLengthError("SQL Procedure schema.name",1,261);04100000
} 04110000
else if( strlen( argv[3] ) < 1 || strlen( argv[3] ) > 8 ) 04120000
{ issueInvalidParmLengthError("Authorization ID",1,8); 04130000
} 04140000
else 04150000
{ strcpy( action, argv[1] ); 04160000
strcpy( routineName, argv[2] ); 04170000
strcpy( authID, argv[3] ); 04180000
} 04190000
04200000
if( argc > 4 ) 04210000
if( strlen( argv[4] ) < 1 || strlen( argv[4] ) > 16 ) 04220000
{ issueInvalidParmLengthError("Server Location Name",1,16); 04230000
} 04240000
else 04250000
strcpy( locationName,argv[4] ); 04260000
else 04270000
locationName[0] = NULLCHAR; 04280000
04290000
} /* end of getCallParms */ 04300000
04310000
04320000
void getReBuildData( void ) /* Get SQL Proc re/build data */ 04330000
/******************************************************************* 04340000
* Collects the prep options and source data needed by DSNTPSMP to * 04350000
* perform a BUILD or REBUILD operation. * 04360000
*******************************************************************/ 04370000
{ 04380000
/***************************************************************** 04390000
* Get program prep, bind, and runtime options * 04400000
*****************************************************************/ 04410000
getOptions( precompOptions,255,"PCOPTS" ); 04420000
if( rc < RETSEV ) 04430000
getOptions( compileOptions,255,"COPTS" ); 04440000
if( rc < RETSEV ) 04450000
getOptions( prelinkOptions,255,"PLKDOPTS" ); 04460000
if( rc < RETSEV ) 04470000
getOptions( linkOptions,255,"LKEDOPTS" ); 04480000
if( rc < RETSEV ) 04490000
getOptions( bindOptions,1024,"BINDOPTS" ); 04500000
/* if( rc < RETSEV ) @02*/ 04510000
/* getOptions( LeOptions,254,"LEOPTS" ); @02*/ 04520000
04530000
/***************************************************************** 04540000
* Get the source for the SQL procedure to be prepared * 04550000
*****************************************************************/ 04560000
if( rc < RETSEV ) 04570000
getSqlSource(); 04580000
} /* end of getReBuildData */ 04590000
04600000
04610000
void getDestroyData( void ) /* Get SQL Proc destroy data */ 04620000
/******************************************************************* 04630000
* Gets the name of the package to be freed by DSNTPSMP during a * 04640000
* DESTROY operation. * 04650000
*******************************************************************/ 04660000
{ 04670000
/***************************************************************** 04680000
* Set program prep and runtime options to NULLCHAR * 04690000
*****************************************************************/ 04700000
sqlSource.length = 0; /*@05*/ 04710004
sqlSource.data[0] = NULLCHAR; /*@05*/ 04720004
precompOptions[0] = NULLCHAR; 04730000
compileOptions[0] = NULLCHAR; 04740000
prelinkOptions[0] = NULLCHAR; 04750000
linkOptions[0] = NULLCHAR; 04760000
alterStmt[0] = NULLCHAR; /*@02*/ 04770000
sqlSourceDsn[0] = NULLCHAR; 04780000
outputString[0] = NULLCHAR; 04790000
04800000
/***************************************************************** 04810000
* Get name of package to free * 04820000
*****************************************************************/ 04830000
getOptions( bindOptions,1024,"BINDOPTS" ); 04840000
04850000
} /* end of getDestroyData */ 04860000
04870000
04880000
void getRebindData( void ) /* Rebind an SQL Procedure */ 04890000
/******************************************************************* 04900000
* Gets the name of the package to be rebound by DSNTPSMP during a * 04910000
* REBIND operation. * 04920000
*******************************************************************/ 04930000
{ 04940000
/***************************************************************** 04950000
* Set program prep and runtime options to NULLCHAR * 04960000
*****************************************************************/ 04970000
sqlSource.length = 0; /*@05*/ 04980004
sqlSource.data[0] = NULLCHAR; /*@05*/ 04990004
precompOptions[0] = NULLCHAR; 05000000
compileOptions[0] = NULLCHAR; 05010000
prelinkOptions[0] = NULLCHAR; 05020000
linkOptions[0] = NULLCHAR; 05030000
alterStmt[0] = NULLCHAR; /*@02*/ 05040000
sqlSourceDsn[0] = NULLCHAR; 05050000
outputString[0] = NULLCHAR; 05060000
05070000
/***************************************************************** 05080000
* Get parameters to pass for rebind * 05090000
*****************************************************************/ 05100000
getOptions( bindOptions,1024,"BINDOPTS" ); 05110000
05120000
} /* end of getRebindData */ 05130000
05140000
05150000
void getLevelData( void ) /* QueryLevel of DSNTPSMP */ 05160003
/******************************************************************* 05170003
* Prepare for a DSNTPSMP QUERYLEVEL operation. * 05180003
*******************************************************************/ 05190003
{ 05200003
/***************************************************************** 05210003
* Set program prep and runtime options to NULLCHAR * 05220003
*****************************************************************/ 05230003
sqlSource.length = 0; /*@05*/ 05240004
sqlSource.data[0] = NULLCHAR; /*@05*/ 05250004
precompOptions[0] = NULLCHAR; 05260003
compileOptions[0] = NULLCHAR; 05270003
prelinkOptions[0] = NULLCHAR; 05280003
linkOptions[0] = NULLCHAR; 05290003
alterStmt[0] = NULLCHAR; /*@02*/ 05300003
sqlSourceDsn[0] = NULLCHAR; 05310003
outputString[0] = NULLCHAR; 05320003
05330003
} /* end of getLevelData */ 05340003
05350003
05360003
void getOptions /* Read processing options */ 05370000
( char *options, /* -out: list of options read */ 05380000
int maxBytes, /* - in: max size of list */ 05390000
char *optionsDDname /* - in: nameof DD to read */ 05400000
) 05410000
/******************************************************************* 05420000
* Reads up to maxBytes bytes of data from optionsDDname into the * 05430000
* options buffer. * 05440000
*******************************************************************/ 05450000
{ FILE *optionsFile; /* Ptr to specified options DD*/ 05460000
char optionsDD[12]; /* DD handle */ 05470000
char optionsRec[80]; /* Options file input record */ 05480000
short int recordLength = 0; /* Length of record */ 05490000
unsigned short moreRecords = Yes; /* EOF indicator */ 05500000
05510000
sprintf( optionsDD, 05520000
"DD:%s\0", 05530000
optionsDDname ); 05540000
05550000
errno = 0; /* clear LE errno */ 05560000
optionsFile = fopen( optionsDD, 05570000
"rb,lrecl=80,type=record" ); 05580000
if( optionsFile == NULL ) 05590000
issueDataSetOpeningError( optionsDD,errno ); 05600000
05610000
while( moreRecords == Yes && rc < RETSEV ) 05620000
{ recordLength 05630000
= fread( optionsRec, /* Read into options rec area */ 05640000
1, /* ..1 record */ 05650000
80, /* ..of 80 bytes */ 05660000
optionsFile ); /* ..from current options file*/ 05670000
05680000
if( ferror(optionsFile) ) /* Handle IO errors */ 05690000
issueDataSetReadingError( optionsDD,errno ); 05700000
05710000
else if( feof(optionsFile) ) /* Handle EOF */ 05720000
moreRecords = No; 05730000
/* Discard bytes 73-80 and */ 05740000
else /* strip off trailing blanks */ 05750000
{ strncat( options,optionsRec,72 ); 05760000
trimTrailingBlanks( options ); 05770000
/* Remove +/- continuation chars from BIND input @03*/ 05780000
if( memcmp( optionsDDname,"BINDOPTS",8 ) == 0 ) /*@03*/ 05790000
stripContinuationCharacter( options ); /*@03*/ 05800000
} 05810000
/* Don't overfill return area */ 05820000
if( rc < RETSEV && strlen(options) > maxBytes ) 05830000
issueInvalidParmLengthError( optionsDD,0,maxBytes ); 05840000
} 05850000
05860000
if( rc < RETSEV ) 05870000
if( fclose( optionsFile ) != 0 ) 05880000
issueDataSetClosingError( optionsDD,errno ); 05890000
05900000
} /* end of getOptions */ 05910000
05920000
05930000
void getSqlSource( void ) /* Read SQL Procedure Source */ 05940000
/******************************************************************* 05950000
* Reads up to 2M bytes of SQL Procedure source code from the * 05960000
* SQLIN DD. * 05970000
*******************************************************************/ 05980000
{ char sourceRec[80]; /* Source file input record */ 05990000
short int recordLength = 0; /* Length of record */ 06000000
unsigned short moreRecords = Yes; /* EOF indicator */ 06010000
06020000
/***************************************************************** 06030000
* Open the data set having the source for the SQL Procedure * 06040000
*****************************************************************/ 06050000
errno = 0; /* clear LE errno */ 06060000
sqlInFile = fopen( "DD:SQLIN", 06070000
"rb,lrecl=80,type=record" ); 06080000
if( sqlInFile == NULL ) 06090000
issueDataSetOpeningError( "DD:SQLIN",errno ); 06100000
06110000
while( moreRecords == Yes && rc < RETSEV ) 06120000
{ recordLength 06130000
= fread( sourceRec, /* Read into source rec area */ 06140000
1, /* ..1 record */ 06150000
80, /* ..of 80 bytes */ 06160000
sqlInFile ); /* ..from SQL Proc source file*/ 06170000
06180000
if( ferror(sqlInFile) ) /* Handle IO errors */ 06190000
issueDataSetReadingError( "DD:SQLIN",errno ); 06200000
06210000
else if( feof(sqlInFile) ) /* Handle EOF */ 06220000
moreRecords = No; 06230000
/* Discard bytes 73-80, strip */ 06240000
else /* trailing blanks,add NL char*/ 06250000
{ sourceRec[72] = NULLCHAR; 06260000
trimTrailingBlanks( sourceRec ); 06270000
strncat( sourceRec,"\x25",1 ); 06280000
strcat( sqlSource.data, sourceRec ); 06290000
sqlSource.length = strlen(sqlSource.data); 06300003
} 06310000
/* Throw exception if not enough room for next record ... */ 06320003
if( moreRecords == Yes && sqlSource.length >((2*1048576)-72) ) 06330003
issueInvalidParmLengthError( "DD:SQLIN",0,((2*1048576)-72) ); 06340000
} 06350000
06360000
if( rc < RETSEV ) 06370000
if( fclose( sqlInFile ) != 0 ) 06380000
issueDataSetClosingError( "DD:SQLIN",errno ); 06390000
06400000
} /* end of getSQLsource */ 06410000
06420000
06430000
void connectToLocation( void ) /* Connect to DB2 location */ 06440000
/******************************************************************* 06450000
* Connects to the DB2 location specified in call parm number 4 * 06460000
*******************************************************************/ 06470000
{ EXEC SQL 06480000
CONNECT TO :locationName; 06490000
06500000
if( SQLCODE != 0 ) 06510000
{ issueSqlError( "Connect to location failed" ); 06520000
} 06530000
} /* end of connectToLocation */ 06540000
06550000
06560003
void setAuthID( void ) /* Set the current DB2 auth id*/ 06570003
/******************************************************************* 06580003
* Changes the current authorization id to the one specified in * 06590003
* call parm number 3 * 06600003
*******************************************************************/ 06610003
{ EXEC SQL 06620003
SET CURRENT SQLID = :authID; 06630003
06640003
if( SQLCODE != 0 ) 06650003
{ issueSqlError( "Set current SQLID failed" ); 06660003
} 06670003
} /* end of setAuthID */ 06680003
06690003
06700000
void callDSNTPSMP( void ) /* Run SQL Procedure Processor*/ 06710000
/******************************************************************* 06720000
* Calls the DSNTPSMP (DB2 SQL Procedures Processor) * 06730000
*******************************************************************/ 06740000
{ listDSNTPSMPcallParms(); 06750000
06760000
EXEC SQL 06770000
CALL SYSPROC.DSNTPSMP( :action, 06780000
:routineName, 06790000
:sqlSource, 06800000
:bindOptions, 06810000
:compileOptions, 06820000
:precompOptions, 06830000
:prelinkOptions, 06840000
:linkOptions, 06850000
:alterStmt, /*@02*/ 06860000
:sqlSourceDsn, 06870000
:authID, /*@05*/ 06880004
:DSNTPSMP_pname, /*@05*/ 06890004
:outputString ); 06900000
06910000
/***************************************************************** 06920000
* Analyze status codes from DSNTPSMP * 06930000
*****************************************************************/ 06940000
printf( "* DSNTPSMP has completed with return code %s\n", 06950000
outputString ); 06960000
if( SQLCODE != 0 && SQLCODE != 466 ) /*+@04*/ 06970000
{ issueSqlError( "Call to DSNTPSMP failed" ); 06980000
} 06990000
else if( levelquery != 'Y' ) 07000000
{ DSNTPSMP_rc = atoi( outputString ); 07010000
if( SQLCODE == 466 ) 07020000
resultSetReturned = Yes; 07030000
else /* SQLCODE == 0 */ 07040000
resultSetReturned = No; 07050000
} /*-@04*/ 07060000
else /* levelquery == 'Y' */ 07070003
{ DSNTPSMP_rc=0; /* not applicable */ 07080003
if( SQLCODE == 466 ) 07090003
resultSetReturned = Yes; 07100003
else /* SQLCODE == 0 */ 07110003
resultSetReturned = No; 07120003
/* Check that level returned matches to the TENTHS digit. */ 07130003
if( memcmp( outputString,INTERFACE,3 ) != 0 ) 07140003
issueInvalidLevelError( outputString ); 07150003
} 07160003
07170000
} /* end of callDSNTPSMP */ 07180000
07190000
07200000
void listDSNTPSMPcallParms( void ) /* List parms sent to DSNTPSMP*/ 07210000
/******************************************************************* 07220000
* Displays the arguments of parameters being passed to DSNTPSMP * 07230000
*******************************************************************/ 07240000
{ printf( "****************************************" 07250000
"****************************************\n" ); 07260000
printf( "* DSN8ED4 is now invoking the DB2 SQL Procedures " 07270000
"Processor (SYSPROC.DSNTPSMP)\n" ); 07280000
printf( "*\n" ); 07290000
printf( "* Location name: %s\n", locationName ); 07300000
printf( "*\n" ); 07310000
printf( "* Action specified: %s\n", action ); 07320000
printf( "*\n" ); 07330000
printf( "* SQL Procedure name: %s\n", routineName ); 07340000
printf( "*\n" ); 07350000
printf( "* DB2 Precompiler Options:\n* %s\n", precompOptions ); 07360000
printf( "*\n" ); 07370000
printf( "* Compiler Options:\n* %s\n", compileOptions ); 07380000
printf( "*\n" ); 07390000
printf( "* Prelink Editor Options:\n* %s\n", prelinkOptions ); 07400000
printf( "*\n" ); 07410000
printf( "* Link Editor Options:\n* %s\n", linkOptions ); 07420000
printf( "*\n" ); 07430000
printf( "* DB2 Bind Options:\n* %s\n", bindOptions ); 07440000
printf( "*\n" ); 07450000
if( strlen(alterStmt) > 0 ) /*@02*/ 07460000
{ /*@02*/ 07470000
printf( "* ALTER statement:\n* %s\n", alterStmt ); /*@02*/ 07480000
printf( "*\n" ); 07490000
} /*@02*/ 07500000
07510000
} /* end of listDSNTPSMPcallParms */ 07520000
07530000
07540000
void processDSNTPSMPresultSet( void ) /* Handle DSNTPSMP result sets*/ 07550000
/******************************************************************* 07560000
* Outputs data from the result set returned by DSNTPSMP * 07570000
*******************************************************************/ 07580000
{ 07590000
/***************************************************************** 07600000
* Associate a locator with the result set from DSNTPSMP * 07610000
*****************************************************************/ 07620000
associateResultSetLocator(); 07630000
07640000
/***************************************************************** 07650000
* Allocate a cursor for the result set * 07660000
*****************************************************************/ 07670000
if( rc < RETSEV ) 07680000
allocateResultSetCursor(); 07690000
07700000
/***************************************************************** 07710000
* Output reports returned in the result set * 07720000
*****************************************************************/ 07730000
if( rc < RETSEV ) 07740000
writeDSNTPSMPreports(); 07750000
07760000
} /* end of processDSNTPSMPresultSet */ 07770000
07780000
07790000
void associateResultSetLocator(void) /* Assoc DSNTPSMP RS locator */ 07800000
/******************************************************************* 07810000
* Associates the result set from DSNTPSMP with a result set locator* 07820000
*******************************************************************/ 07830000
{ EXEC SQL 07840000
ASSOCIATE 07850000
LOCATORS( :DSNTPSMP_rs_loc1 ) 07860000
WITH PROCEDURE SYSPROC.DSNTPSMP; 07870000
07880000
if( SQLCODE != 0 ) 07890000
{ issueSqlError( "Associate locator call failed" ); 07900000
} 07910000
07920000
} /* end of associateResultSetLocator */ 07930000
07940000
07950000
void allocateResultSetCursor( void ) /* Alloc DSNTPSMP RS cursor */ 07960000
/******************************************************************* 07970000
* Allocates a cursor to the locator for the DSNTPSMP result set * 07980000
*******************************************************************/ 07990000
{ EXEC SQL 08000000
ALLOCATE DSNTPSMP_RS_CSR1 08010000
CURSOR FOR RESULT SET :DSNTPSMP_rs_loc1; 08020000
08030000
if( SQLCODE != 0 ) 08040000
{ issueSqlError( "Allocate result set cursor " 08050000
"call failed" ); 08060000
} 08070000
08080000
} /* end of allocateResultSetCursor */ 08090000
08100000
08110000
void writeDSNTPSMPreports( void ) /* Print DSNTPSMP report */ 08120000
/******************************************************************* 08130000
* Outputs the reports returned in the result set from DSNTPSMP * 08140000
******************************************************************** 08150000
* The result set returned by DSNTPSMP contains one or more reports.* 08160000
* * 08170000
* Within the result set, reports are distinguished from one anoth- * 08180000
* er by the STEP and FILE columns: * 08190000
* - STEP refers to the phase (e.g. precompile, compile, bind, etc.)* 08200000
* of DSNTPSMP that generated the report. * 08210000
* - FILE distinguishes reports that are generated by the same STEP.* 08220000
* * 08230000
* Report line data are stored in the LINE column, and arranged ac- * 08240000
* cording to the sequence number in the SEQN column. * 08250000
* * 08260000
* In summary, STEPs contain FILEs, FILEs contain LINEs, and LINEs * 08270000
* are ordered according to SEQN (sequence). * 08280000
*******************************************************************/ 08290000
{ short int reportNumber = 1; /* Sequence number of report */ 08300000
char prevStepName[17]; /* Track step name changes */ 08310000
char prevFileName[9]; /* Track file name changes */ 08320000
short int recordLength = 0; /* Length of record */ 08330000
08340000
/***************************************************************** 08350000
* Get the first entry in the result set * 08360000
*****************************************************************/ 08370000
fetchFromResultSetCursor(); 08380000
08390000
/***************************************************************** 08400000
* Allocate an outout DD for the first report * 08410000
*****************************************************************/ 08420000
if( rc < RETSEV ) 08430000
openReportDataSet( reportNumber ); 08440000
08450000
/***************************************************************** 08460000
* Save step and file, to monitor for when they change * 08470000
*****************************************************************/ 08480000
if( rc < RETSEV ) 08490000
{ strncpy( prevStepName,stepName,17 ); 08500000
strncpy( prevFileName,fileName,9 ); 08510000
} 08520000
08530000
/***************************************************************** 08540000
* Process all rows in the result set * 08550000
*****************************************************************/ 08560000
while( SQLCODE == 0 && rc < RETSEV ) 08570000
{ if( ( strcmp( prevStepName,stepName ) != 0 08580005
|| strcmp( prevFileName,fileName ) != 0 ) 08590005
&& reportNumber < 6 ) /*@06*/ 08600005
/*********************************************************** 08610000
* If the step or file changes, allocate next report DD * 08620000
* up to and including report no. 6 @06* 08630005
***********************************************************/ 08640000
{ closeReportDataSet(); 08650000
if( rc < RETSEV ) 08660000
openReportDataSet( ++reportNumber ); 08670000
if( rc < RETSEV ) 08680000
{ strncpy( prevStepName,stepName,17 ); 08690000
strncpy( prevFileName,fileName,9 ); 08700000
} 08710000
} 08720000
/************************************************************* 08730000
* Write the current report line to the current report DD * 08740000
*************************************************************/ 08750000
if( rc < RETSEV ) 08760000
{ recordLength 08770000
= fwrite( reportLine, /* write from reportLine */ 08780000
1, /* ..a record */ 08790000
sizeof( reportLine ), 08800000
reportDD ); /* ..into the report data set */ 08810000
} 08820000
if( rc < RETSEV ) 08830000
{ fetchFromResultSetCursor(); 08840000
} 08850000
} 08860000
08870000
if( rc < RETSEV ) 08880000
{ closeReportDataSet(); 08890000
} 08900000
08910000
} /* end of writeDSNTPSMPreports */ 08920000
08930000
08940000
void fetchFromResultSetCursor( void ) /* Read DSNTSPMP RS cursor */ 08950000
/******************************************************************* 08960000
* Reads the cursor for the DSNTPSMP result set * 08970000
*******************************************************************/ 08980000
{ memset( reportLine,' ',256 ); 08990000
09000000
EXEC SQL 09010000
FETCH DSNTPSMP_RS_CSR1 09020000
INTO :stepName, 09030000
:fileName, 09040000
:reportLineNumber, 09050000
:reportLine; 09060000
09070000
if( SQLCODE != 0 && SQLCODE != 100 && rc < RETSEV ) 09080000
{ issueSqlError( "*** Fetch from " 09090000
"result set cursor failed" ); 09100000
} 09110000
} /* end of fetchFromResultSetCursor */ 09120000
09130000
09140000
void openReportDataSet /* Alloc DD for a report */ 09150000
( short int reportNumber /* - in: Seqeunce number */ 09160000
) 09170000
/******************************************************************* 09180000
* Opens the DD REPORTnn, where "nn" is the report number passed in * 09190000
* and associates it with the file handler reportDD. * 09200000
*******************************************************************/ 09210000
{ char reportDDdcb[36]; /* for generated DCB */ 09220000
09230000
if( reportNumber < 1 || reportNumber > 99 ) 09240000
issueInvalidDDnumError( reportNumber ); 09250000
09260000
else 09270000
{ sprintf( reportDDName, /* Generate DD name REPORTnn */ 09280000
"DD:REPORT%2.2i\0", /* ..where nn is the sequence */ 09290000
reportNumber ); /* ..number of the report */ 09300000
09310000
if( reportLine[0] == '1' ) /* Does this look like FBA? */ 09320000
sprintf( reportDDdcb, /* Yes: Specify */ 09330000
"wb,recfm=FBA," /* ..record output, recfm=fba */ 09340000
"lrecl=256" ); /* ..and lrecl 255 */ 09350000
else 09360000
sprintf( reportDDdcb, /* No: Specify */ 09370000
"wb,recfm=FB," /* ..record output, recfm=fb */ 09380000
"lrecl=256" ); /* ..and lrecl 255 */ 09390000
09400000
errno = 0; /* clear LE errno */ 09410000
reportDD = fopen( reportDDName,reportDDdcb ); 09420000
09430000
if( reportDD == NULL ) /* If unable to open data set */ 09440000
issueDataSetOpeningError( reportDDName,errno ); 09450000
} 09460000
} /* end of openReportDataSet */ 09470000
09480000
09490000
void closeReportDataSet( void ) /* Dealloc DD for a report */ 09500000
/******************************************************************* 09510000
* Closes the DD associated with the file handler reportDD. * 09520000
*******************************************************************/ 09530000
{ if( fclose(reportDD) != 0 ) 09540000
issueDataSetClosingError( reportDDName,errno ); 09550000
} /* end of closeReportDataSet */ 09560000
09570000
09580000
void trimTrailingBlanks /* Strip off trailing blanks */ 09590000
( char *string /* - in: string to be trimmed */ 09600000
) 09610000
/******************************************************************* 09620000
* Strips trailing blanks from a string * 09630000
*******************************************************************/ 09640000
{ int i; 09650000
for( i = strlen(string) - 1; string[i] == ' '; i-- ); 09660000
string[++i] = '\0'; 09670000
} /* end of trimTrailingBlanks */ 09680000
09690000
/*begin @03*/ 09700000
void stripContinuationCharacter /* Strip off trailing - or + */ 09710000
( char *string /* - in: string to be trimmed */ 09720000
) 09730000
/******************************************************************* 09740000
* Strips trailing '+' or '-' from a blank-trimmed string * 09750000
*******************************************************************/ 09760000
{ int i; 09770000
i = strlen(string) - 1; 09780000
if( string[i] == '+' || string[i] == '-' ) 09790000
string[i] = '\0'; 09800000
trimTrailingBlanks( string ); 09810000
} /* end of trimstripContinuationCharacter */ 09820000
/*end @03*/ 09830000
09840000
/*begin @04*/ 09850000
void processSqlCommit( void ) /* Commit SQL changes */ 09860000
/******************************************************************* 09870000
* Commits the current unit of SQL work * 09880000
*******************************************************************/ 09890000
{ EXEC SQL 09900000
COMMIT; 09910000
09920000
if( SQLCODE != 0 ) 09930000
{ issueSqlError( "*** Commit failed " ); 09940000
} 09950000
else 09960000
{ printf( "* SQL changes have been committed\n" ); 09970000
} 09980000
09990000
} /* end of processSqlCommit */ 10000000
10010000
10020000
void processSqlRollback( void ) /* Rollback SQL changes */ 10030000
/******************************************************************* 10040000
* Rolls back the current unit of SQL work * 10050000
*******************************************************************/ 10060000
{ EXEC SQL 10070000
ROLLBACK; 10080000
10090000
if( SQLCODE != 0 ) 10100000
{ issueSqlError( "*** Rollback failed " ); 10110000
} 10120000
else 10130000
{ printf( "* SQL changes have been rolled back\n" ); 10140000
} 10150000
10160000
} /* end of processSqlRollback */ 10170000
/*end @04*/ 10180000
10190000
void issueDataSetClosingError /* Handler for ds close error */ 10200000
( char *DDname, /* - in: name of errant DD */ 10210000
int LEerrno /* - in: LE diagnostic errno */ 10220000
) 10230000
/******************************************************************* 10240000
* Called when a TSO data set cannot be closed * 10250000
*******************************************************************/ 10260000
{ printf( "ERROR: Unable to close %s\n", DDname ); 10270000
printf( "%s \n",strerror(LEerrno) ); 10280000
printf( "-----> Processing halted\n" ); 10290000
rc = RETSEV; 10300000
} /* end of issueDataSetClosingError */ 10310000
10320000
10330000
void issueDataSetOpeningError /* Handler for ds open error */ 10340000
( char *DDname, /* - in: name of errant DD */ 10350000
int LEerrno /* - in: LE diagnostic errno */ 10360000
) 10370000
/******************************************************************* 10380000
* Called when a TSO data set cannot be opened * 10390000
*******************************************************************/ 10400000
{ printf( "ERROR: Unable to open %s\n", DDname ); 10410000
printf( "%s \n",strerror(LEerrno) ); 10420000
printf( "-----> Processing halted\n" ); 10430000
rc = RETSEV; 10440000
} /* end of issueDataSetOpeningError */ 10450000
10460000
10470000
void issueDataSetReadingError /* Handler for ds read error */ 10480000
( char *DDname, /* - in: name of errant DD */ 10490000
int LEerrno /* - in: LE diagnostic errno */ 10500000
) 10510000
/******************************************************************* 10520000
* Called when a TSO data set cannot be read * 10530000
*******************************************************************/ 10540000
{ printf( "ERROR: Unable to read %s\n", DDname ); 10550000
printf( "%s \n",strerror(LEerrno) ); 10560000
printf( "-----> Processing halted\n" ); 10570000
rc = RETSEV; 10580000
} /* end of issueDataSetReadingError */ 10590000
10600000
10610000
void issueInvalidCallParmCountError /* Handler for parm count err */ 10620000
( int argc /* - in: no. parms received */ 10630000
) 10640000
/******************************************************************* 10650000
* Called when this program is invoked with an inappropriate number * 10660000
* of call parms. * 10670000
*******************************************************************/ 10680000
{ printf( "ERROR: DSN8ED4 was invoked with %i parameters\n",--argc );10690000
printf( " - The first three parms (action, routine " 10700000
"name, and authid) are required\n" ); 10710000
printf( " - The fourth parm (location name) " 10720000
"is optional\n" ); 10730000
printf( "-----> Processing halted\n" ); 10740000
rc = RETSEV; 10750000
} /* end of issueInvalidCallParmCountError */ 10760000
10770000
10780000
void issueInvalidDDnumError /* Handler for unknown DD seq */ 10790000
( short invalidDDnum /* - in: invalid DD sequ. no. */ 10800000
) 10810000
/******************************************************************* 10820000
* Called when the sequence number for a report DD (REPORTnn, where * 10830000
* "nn" is the sequence number" is less than 1 or greater 99. * 10840000
*******************************************************************/ 10850000
{ printf( "ERROR: Invalid sequence "/* Issue error messages */ 10860000
"number <%i> specified " /* ..for DD REPORTnn */ 10870000
"for REPORTnn DD\n", /* ..where nn is the sequence */ 10880000
invalidDDnum ); /* ..number of the result set */ 10890000
printf( "-----> Processing halted\n" ); 10900000
rc = RETSEV; 10910000
} /* end of issueInvalidDDnumError */ 10920000
10930000
10940000
void issueInvalidActionError /* Handler for unknown action */ 10950000
( char *action /* - in: action specified */ 10960000
) 10970000
/******************************************************************* 10980000
* Called when an unexpected argument is specified for the DB2 SQL * 10990000
* Procedures Processor action * 11000000
*******************************************************************/ 11010000
{ printf( "ERROR: The argument specified for the action " 11020000
"parameter is invalid\n",action ); 11030000
printf( "-----> Processing halted\n" ); 11040000
rc = RETSEV; 11050000
} /* end of issueInvalidActionError */ 11060000
11070000
11080000
void issueInvalidParmLengthError /* Handler for parm len error */ 11090000
( char *parmName, /* - in: identify of parm */ 11100000
int minLength, /* - in: min valid length */ 11110000
int maxLength /* - in: max valid length */ 11120000
) 11130000
/******************************************************************* 11140000
* Called when the length of an argument specified for a DSNTPSMP * 11150000
* parameter (parmName) does not fall within the valid bounds for * 11160000
* size (minLength and maxLength) for that parameter * 11170000
*******************************************************************/ 11180000
{ printf( "ERROR: The length of the argument specified for the %s " 11190000
"parameter\n",parmName ); 11200000
printf( " does not fall within the required bounds of %i " 11210000
"and %i\n",minLength,maxLength ); 11220000
printf( "-----> Processing halted\n" ); 11230000
rc = RETSEV; 11240000
} /* end of issueInvalidParmLengthError */ 11250000
11260003
11270003
void issueInvalidLevelError /* Handler for wrong DSNTPSMP */ 11280003
( char *level /* - in: level encountered */ 11290003
) 11300003
/******************************************************************* 11310003
* Called when a DSNTPSMP QUERYLEVEL request returns a level not * 11320003
* handled by this sample client. * 11330003
*******************************************************************/ 11340003
{ printf( "ERROR: The DSNTPSMP interface level %s is not " 11350003
"supported by this client\n",level ); 11360003
printf( "-----> Processing halted\n" ); 11370003
rc = RETSEV; 11380003
} /* end of issueInvalidLevelError */ 11390003
11400000
11410000
#pragma linkage(dsntiar, OS) 11420000
void issueSqlError /* Handler for SQL error */ 11430000
( char *locMsg /* - in: Call location */ 11440000
) 11450000
/******************************************************************* 11460000
* Called when an unexpected SQLCODE is returned from a DB2 call * 11470000
*******************************************************************/ 11480000
{ struct error_struct { /* DSNTIAR message structure */ 11490000
short int error_len; 11500000
char error_text[10][80]; 11510000
} error_message = {10 * 80}; 11520000
11530000
extern short int dsntiar( struct sqlca *sqlca, 11540000
struct error_struct *msg, 11550000
int *len ); 11560000
11570000
short int DSNTIARrc; /* DSNTIAR Return code */ 11580000
int j; /* Loop control */ 11590000
static int lrecl = 80; /* Width of message lines */ 11600000
11610000
/***************************************************************** 11620000
* print the locator message * 11630000
*****************************************************************/ 11640000
printf( "ERROR: %-80s\n", locMsg ); 11650000
printf( "-----> Processing halted\n" ); 11660000
11670000
/***************************************************************** 11680000
* format and print the SQL message * 11690000
*****************************************************************/ 11700000
DSNTIARrc = dsntiar( &sqlca, &error_message, &lrecl ); 11710000
if( DSNTIARrc == 0 ) 11720000
for( j = 0; j <= 10; j++ ) 11730000
printf( " %.80s\n", error_message.error_text[j] ); 11740000
else 11750000
{ 11760000
printf( " *** ERROR: DSNTIAR could not format the message\n" );11770000
printf( " *** SQLCODE is %d\n",SQLCODE ); 11780000
printf( " *** SQLERRM is \n" ); 11790000
for( j=0; j<sqlca.sqlerrml; j++ ) 11800000
printf( "%c", sqlca.sqlerrmc[j] ); 11810000
printf( "\n" ); 11820000
} 11830000
11840000
/***************************************************************** 11850000
* set severe error code * 11860000
*****************************************************************/ 11870000
rc = RETSEV; 11880000
11890000
} /* end of issueSqlError */ 11900000