根据动态sql语句 dyn_statement = select sfzh from ls where rownum=1;
sfzh 应该为18位身份证号,但是如果sfzh是varchar2型,结果只能返回17位的数据,
而改成char(18)的结构,就能查出正确的18位身份证号,请高手指点一下
SQLDA * bind_dp;
SQLDA * select_dp;int process_select_list()
{
/*
* define the TSQ buffer to store select list value
* ptrbuf used to maintain the forward pointer
* initialized with head of TSQ buffer
*/
char tsqbuf[32000]="";
char *ptrbuf=NULL;
char strTemp[4001]=""; /*definition for indivual field*/
char strTmp[80]=""; /*definition for temp storage*/
int iColNum = 0;
int iMaxRecLen = 0;
long lTotalQLen = 0; int i, null_ok, precision, scale;
if ((strncmp(dyn_statement, "SELECT", 6) != 0) &&
(strncmp(dyn_statement, "select", 6) != 0))
{ select_dp->F = 0; strcpy((char*)sErrCode,ESQL_SUCCESS);
caResetCommArea (&MyCommArea);
MyCommArea.caReturnCode = ERROR_SUCCESS; caAddField( &MyCommArea, (unsigned char*)sErrCode );
caMakeCommArea( commArea, &MyCommArea );
return RET_OTHER;
}
/* If the SQL statement is a SELECT, describe the
select-list items. The DESCRIBE function returns
their names, datatypes, lengths (including precision
and scale), and NULL/NOT NULL statuses.
*/ select_dp->N = MAX_ITEMS;
EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp;
if ( sqlca.sqlcode != 0 )
{
TraceError(ESQL_SELECTLIST,ERROR_SYSTEM);
} /* If F is negative, there were more select-list
items than originally allocated by sqlald(). */
if (select_dp->F < 0)
{
printf ("\nToo many select-list items (%d), maximum is %d\n",
-(select_dp->F), MAX_ITEMS);
return RET_ERROR;
} /* Set the maximum number of array elements in the
descriptor to the number found. */
select_dp->N = select_dp->F; /* Allocate storage for each select-list item.
sqlprc() is used to extract precision and scale
from the length (select_dp->L[i]). sqlnul() is used to reset the high-order bit of
the datatype and to check whether the column
is NOT NULL. CHAR datatypes have length, but zero precision and
scale. The length is defined at CREATE time. NUMBER datatypes have precision and scale only if
defined at CREATE time. If the column
definition was just NUMBER, the precision
and scale are zero, and you must allocate
the required maximum length. DATE datatypes return a length of 7 if the default
format is used. This should be increased to
9 to store the actual date character string.
If you use the TO_CHAR function, the maximum
length could be 75, but will probably be less
(you can see the effects of this in SQL*Plus). ROWID datatype always returns a fixed length of 18 if
coerced to CHAR. LONG and
LONG RAW datatypes return a length of 0 (zero),
so you need to set a maximum. In this example,
it is 240 characters. */
fprintf(stderr," select_dp->F---%d\n", select_dp->F);
sfzh 应该为18位身份证号,但是如果sfzh是varchar2型,结果只能返回17位的数据,
而改成char(18)的结构,就能查出正确的18位身份证号,请高手指点一下
SQLDA * bind_dp;
SQLDA * select_dp;int process_select_list()
{
/*
* define the TSQ buffer to store select list value
* ptrbuf used to maintain the forward pointer
* initialized with head of TSQ buffer
*/
char tsqbuf[32000]="";
char *ptrbuf=NULL;
char strTemp[4001]=""; /*definition for indivual field*/
char strTmp[80]=""; /*definition for temp storage*/
int iColNum = 0;
int iMaxRecLen = 0;
long lTotalQLen = 0; int i, null_ok, precision, scale;
if ((strncmp(dyn_statement, "SELECT", 6) != 0) &&
(strncmp(dyn_statement, "select", 6) != 0))
{ select_dp->F = 0; strcpy((char*)sErrCode,ESQL_SUCCESS);
caResetCommArea (&MyCommArea);
MyCommArea.caReturnCode = ERROR_SUCCESS; caAddField( &MyCommArea, (unsigned char*)sErrCode );
caMakeCommArea( commArea, &MyCommArea );
return RET_OTHER;
}
/* If the SQL statement is a SELECT, describe the
select-list items. The DESCRIBE function returns
their names, datatypes, lengths (including precision
and scale), and NULL/NOT NULL statuses.
*/ select_dp->N = MAX_ITEMS;
EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp;
if ( sqlca.sqlcode != 0 )
{
TraceError(ESQL_SELECTLIST,ERROR_SYSTEM);
} /* If F is negative, there were more select-list
items than originally allocated by sqlald(). */
if (select_dp->F < 0)
{
printf ("\nToo many select-list items (%d), maximum is %d\n",
-(select_dp->F), MAX_ITEMS);
return RET_ERROR;
} /* Set the maximum number of array elements in the
descriptor to the number found. */
select_dp->N = select_dp->F; /* Allocate storage for each select-list item.
sqlprc() is used to extract precision and scale
from the length (select_dp->L[i]). sqlnul() is used to reset the high-order bit of
the datatype and to check whether the column
is NOT NULL. CHAR datatypes have length, but zero precision and
scale. The length is defined at CREATE time. NUMBER datatypes have precision and scale only if
defined at CREATE time. If the column
definition was just NUMBER, the precision
and scale are zero, and you must allocate
the required maximum length. DATE datatypes return a length of 7 if the default
format is used. This should be increased to
9 to store the actual date character string.
If you use the TO_CHAR function, the maximum
length could be 75, but will probably be less
(you can see the effects of this in SQL*Plus). ROWID datatype always returns a fixed length of 18 if
coerced to CHAR. LONG and
LONG RAW datatypes return a length of 0 (zero),
so you need to set a maximum. In this example,
it is 240 characters. */
fprintf(stderr," select_dp->F---%d\n", select_dp->F);
{
/* Turn off high-order bit of datatype (in this example,
it does not matter if the column is NOT NULL). */
sqlnul ((unsigned short *)&(select_dp->T[i]), (unsigned short *)&(select_dp->T[i]), &null_ok);
switch (select_dp->T[i])
{
case 1 : /* CHAR datatype: no change in length
needed, except possibly for TO_CHAR
conversions (not handled here). */
fprintf(stderr,"magiccase1[i]=%d\n",i);
break;
case 2 : /* NUMBER datatype: use sqlprc() to
extract precision and scale. */
sqlprc ((unsigned long *)&(select_dp->L[i]), &precision, &scale); /* Allow for maximum size of NUMBER. */
if (precision == 0) precision = 40;
/* Also allow for decimal point and
possible sign. */
/* convert NUMBER datatype to FLOAT if scale > 0,
INT otherwise. */ if (scale > 0)
select_dp->L[i] = sizeof(float);
else
select_dp->L[i] = sizeof(int); break; case 8 : /* LONG datatype */
select_dp->L[i] = 240;
break; case 11 : /* ROWID datatype */
select_dp->L[i] = 18;
break; case 12 : /* DATE datatype */
select_dp->L[i] = 9;
break;
case 23 : /* RAW datatype */
break; case 24 : /* LONG RAW datatype */
select_dp->L[i] = 240;
break;
}
/* Allocate space for the select-list data values.
sqlald() reserves a pointer location for
V[i] but does not allocate the full space for
the pointer. */
/*fprintf(stderr,"before realloc,old addr=%x,i=%d,T[i]=%d\n",select_dp->V[i],i,select_dp->T[i]); */
if (select_dp->T[i] != 2) {
fprintf(stderr,"realloc,=2,old---%x,i=%d\n",&select_dp->V[i],i);
CICSFREE(select_dp->V[i]);
fprintf(stderr,"我怀疑的出错点\n");
select_dp->V[i] = (char *)CICSMALLOC (select_dp->L[i] + 1);
fprintf(stderr,"magic2:realloc,!=2,newV[i]---%x,i=%d\n",select_dp->V[i],i);
memset( strTemp, 0, sizeof(strTemp) );
memcpy( (void*)strTemp, (void*)select_dp->V[0], select_dp->L[0] );
fprintf(stderr,"magic9:strTemp---[%s]\n\n",strTemp);
}
else {
CICSFREE(select_dp->V[i]);
select_dp->V[i] = (char *) CICSMALLOC(select_dp->L[i]); } /* Coerce ALL datatypes except for LONG RAW and NUMBER to
character. */
if (select_dp->T[i] != 24 && select_dp->T[i] != 2 && select_dp->T[i]!=96 )
select_dp->T[i] = 1; /* Coerce the datatypes of NUMBERs to float or int depending on
the scale. */
if (select_dp->T[i] == 2)
if (scale > 0)
select_dp->T[i] = 4; /* float */
else
select_dp->T[i] = 3; /* int */
if (select_dp->T[i] == 1)
select_dp->T[i] = 5;
fprintf(stderr,"newT[%d]---%d\n",i,select_dp->T[i]);
} /* create tsq */
sb_GetTSQName(gsTsqName, getTaskNumber(dfheiptr->eibtaskn), 1);
giRecordNum=0; caResetCommArea (&MyCommArea);
iColNum = (int) select_dp->F; while(1)
{
memset(tsqbuf,'\0',sizeof(tsqbuf));
ptrbuf = tsqbuf; EXEC SQL FETCH C USING DESCRIPTOR select_dp; if (sqlca.sqlcode==1403) break; /*no rows found*/ if ( sqlca.sqlcode != 0 )
{
TraceError(ESQL_FETCH,ERROR_SYSTEM);
}
fprintf(stderr,"magic10:after fetch :Size of strTemp---[%d]\n\n",sizeof(strTemp) );
fprintf(stderr,"magic10:after fetch :Size of select_dp->V[0]---[%d]\n\n",sizeof(select_dp->V[0]) );
memset( strTemp, 0, sizeof(strTemp) );
memcpy( (void*)strTemp, (void*)select_dp->V[0], 20 );
fprintf(stderr,"magic10:after fetch :strTemp---[%s]\n\n",strTemp);
/* Since each variable returned has been coerced to a
character string, int, or float very little processing
is required here. This routine just output the
values to a temporary variable. */
for (i = 0; i < select_dp->F; i++)
{
memset( strTemp, 0, sizeof(strTemp) );
if (*select_dp->I[i] < 0)
strcpy(strTemp,(const char *)"NULL");
else
if (select_dp->T[i] == 3) /* int datatype */
sprintf(strTemp,"%*d",(int)select_dp->L[i],*(int *)select_dp->V[i]);
else
if (select_dp->T[i] == 4) /* float datatype */
sprintf(strTemp,"%*.2f ", (int)select_dp->L[i], *(float *)select_dp->V[i]);
else
memcpy( (void*)strTemp, (void*)select_dp->V[i], select_dp->L[i] ); strcpy(ptrbuf,strTemp);
ptrbuf += strlen(strTemp) + 1; }
iMaxRecLen = (iMaxRecLen>(ptrbuf-tsqbuf))?iMaxRecLen:(ptrbuf-tsqbuf);
EXEC CICS WRITEQ TS QUEUE(gsTsqName) FROM(tsqbuf) LENGTH( ptrbuf - tsqbuf ) MAIN RESP(ulRespCode); lTotalQLen += ptrbuf - tsqbuf;
giRecordNum++;
} MyCommArea.caReturnCode = ERROR_SUCCESS;
memset( (char*)MyCommArea.caTAG,0,4 );
sprintf( (char*)MyCommArea.caTAG,"%4d",giRecordNum ); /* return tsq name and record num */
caAddField( &MyCommArea, (unsigned char*)gsTsqName); sprintf( (char*)strTmp, "%d", giRecordNum );
caAddField( &MyCommArea, (unsigned char *)strTmp); sprintf( (char*)strTmp, "%d", iColNum );
caAddField( &MyCommArea, (unsigned char *)strTmp); sprintf( (char*)strTmp, "%d", lTotalQLen );
caAddField( &MyCommArea, (unsigned char *)strTmp); sprintf( (char*)strTmp, "%d", iMaxRecLen );
caAddField( &MyCommArea, (unsigned char *)strTmp); caMakeCommArea( commArea, &MyCommArea );
return RET_SELECT;
}
void* CICSMALLOC(short size)
{
unsigned long ulRespCode;
void* pTemp; EXEC CICS GETMAIN SET(pTemp) LENGTH(size) INITIMG(0) RESP(ulRespCode);
if (ulRespCode != DFHRESP(NORMAL))
{
fprintf(stderr, "Error Occure when CICSGETMAIN->will abend, rc=%d\n",ulRespCode);
EXEC CICS ABEND ABCODE("A003");
return -1;
}
else
{
return pTemp;
}
}