| Oracle FAQ | Your Portal to the Oracle Knowledge Grid | |
Home -> Community -> Usenet -> c.d.o.misc -> Re: HELP: Dynamic SQL/Pro*C++ core dumps
By the way, I have the test program running and I thought you might
be interested in the working source. After you run it though you
can see that a double inserted as 1.1111111111e111 is NOT returned
as inserted. It actually returns
1111111111111111419130920033087031241842622669656883858001193965689775666308169623874335331159460917210068811776.000000when it should be
1111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000.That is,
Any suggestions?
Thanks.
Ken
SQL> desc foo;
Name Null? Type ------------------------------- -------- ---- I NUMBER(4) L NUMBER(12) F NUMBER D NUMBER ===================================== #include <stdlib.h> #include <stdio.h>
#include <iostream.h>
extern "C" {
EXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE sqlda;
EXEC SQL INCLUDE sqlcpr;
/* The ORACA=YES option must be specified to enable use of the ORACA */
EXEC ORACLE OPTION (ORACA=YES);
void sql_error(char *msg);
extern void sqlclu( struct SQLDA* );
extern SQLDA *sqlald(int, unsigned int, unsigned int);
extern void sqlnul( unsigned short*, unsigned short*, int* );
extern void sqlprc( unsigned long*, int*, int*);
};
int main( int argc, char** argv ) {
char vtest[50];
int _type;
int v_int;
long v_long;
float v_float;
double v_double;
int v_bv_int = 1;
int i; /* counter variable */ int nullok; /* holder variable for sqlnul() return */ int prec; /* holder variable for sqlprec() */ int scale; /* holder variable for sqlprec() */ SQLDA* sqlda_bv; /* declare sqlda for bind variables */ SQLDA* sqlda_sli; /* declare sqlda for select list items */
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR username[21];
VARCHAR password[21];
EXEC SQL END DECLARE SECTION;
strcpy((char*)username.arr, "sdb3"); username.len = strlen((const char*)username.arr); strcpy((char*)password.arr, "sdb3"); password.len = strlen((const char*)password.arr);
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error");
EXEC SQL CONNECT :username IDENTIFIED BY :password;
/* sqlald(max # of SLI items, max SLI name length, max BV name length)
*/
/* NB: When allocating for a select decriptor always set param 3 to
'0' */
sqlda_bv = sqlald(3,10,10);
sqlda_sli = sqlald(4,10,0);
/* set max # of BVs */
sqlda_bv->N=3;
/* set max # of SLIs */
sqlda_sli->N=4;
EXEC SQL PREPARE stmt1 FROM "select i, l, f, d from foo where i = :id";
EXEC SQL DECLARE curs1 CURSOR FOR stmt1;
EXEC SQL DESCRIBE BIND VARIABLES FOR stmt1 INTO sqlda_bv;
/* Allocate storage for BVs */
sqlda_bv->N=sqlda_bv->F; /* reset N to the value in F */
for(i=1;i<sqlda_bv->F+1;i++) {
/* Setup the I (Indicator Variable) value */
sqlda_bv->I[i-1]=(short *)malloc(sizeof(short *));
*sqlda_bv->I[i-1]=0; /* or set to -1 if NULL value */
/* Setup the T (Datatype) value */
/* sqlda_bv->T[i-1]=1; */
sqlda_bv->T[i-1]=3; /* integer */
/* Setup the L (Length) value */
/* sqlda_bv->L[i-1]=strlen((const char*)v_bv_val); */
sqlda_bv->L[i-1]= sizeof(int);
/* Setup the V (Value/Address) value */
/* sqlda_bv->V[i-1]=v_bv_val; */
sqlda_bv->V[i-1]=(char*)&v_bv_int;
}
EXEC SQL OPEN curs1 USING DESCRIPTOR sqlda_bv;
EXEC SQL DESCRIBE SELECT LIST FOR stmt1 INTO sqlda_sli;
/* printf("\nHere's the value:\t%i",sqlca.sqlerrd[2]); */
/* exit(0); */
/* Allocate storage for SLIs */
sqlda_sli->N=sqlda_sli->F; /* reset N to the value in F */
for(i=1;i<sqlda_sli->F+1;i++)
{
/* Reset the null bit value */
sqlnul((unsigned short*)&sqlda_sli->T[i-1],
(unsigned short*)&sqlda_sli->T[i-1], &nullok);
/* Setup the I (Indicator Variable) value */
sqlda_sli->I[i-1]=(short *)malloc(sizeof(short *));
if (i == 1) _type = 3; /* INTEGER */
if (i == 2) _type = 8; /* LONG */
if (i == 3) _type = 4; /* FLOAT */
if (i == 4) _type = 2; /* NUMBER -- but handle like FLOAT */
/* Setup the L (Length) value and the T (Datatype) value */
switch( _type )
{
/* VARCHAR2 */
case 1: sqlda_sli->T[i-1] = 1;
break;
/* NUMBER -- FLOAT into double */
case 2: sqlprc((unsigned long*)&sqlda_sli->L[i-1],&prec,&scale);
/* sqlda_sli->L[i-1] = sizeof(int); */
sqlda_sli->L[i-1] = sizeof(double);
sqlda_sli->T[i-1] = 4;
sqlda_sli->V[i-1]=(char*) &v_double;
break;
/* INTEGER */
case 3:
/* sqlda_sli->L[i-1] = sizeof(int); */
sqlda_sli->L[i-1] = sizeof(int);
sqlda_sli->T[i-1] = 3;
sqlda_sli->V[i-1]=(char*) &v_int;
break;
/* FLOAT (this is never the case since 4 never occurs */
case 4: sqlprc((unsigned long*)&sqlda_sli->L[i-1],&prec,&scale);
sqlda_sli->L[i-1] = sizeof(float);
sqlda_sli->T[i-1] = 4;
/* Store to a variable */
sqlda_sli->V[i-1]=(char*) &v_float;
/* Store to a sqlda */
/* sqlda_sli->V[i-1]=(char *)malloc((size_t)sqlda_sli->L[i-1]); */
break;
/* PACKED DECIMAL */
case 7: break;
/* LONG */
case 8: sqlprc((unsigned long*)&sqlda_sli->L[i-1],&prec,&scale);
/* sqlda_sli->L[i-1] = sizeof(int); */
sqlda_sli->L[i-1] = sizeof(long);
/* internally to Oracle a number has a defined precision,
therefore, NUMBER(p) is a long if p is greater than the
precision of MAXINT */
sqlda_sli->T[i-1] = 3;
sqlda_sli->V[i-1]=(char*) &v_long;
v_long = 0l;
break;
/* LONG RAW */
case 24: sqlda_sli->L[i-1] = 240;
break;
}
/* Setup the V (Value/Address) value (check for numbers!!) */
if (sqlda_sli->T[i-1]!=2 && sqlda_sli->T[i-1]!=4)
sqlda_sli->V[i-1]=(char *)malloc((size_t)sqlda_sli->L[i-1]);
}
EXEC SQL FETCH curs1 USING DESCRIPTOR sqlda_sli;
printf("insert into foo values (1, 1111111, 1.111e1,
1.111111111111111e111);\n");
v_int = *((int*)(sqlda_sli->V[0]));
printf( "sli int: %i \n", *((int*)(sqlda_sli->V[0])) );
printf( " v_int: %i \n", v_int );
v_long = *((long*)(sqlda_sli->V[1]));
printf( "sli long: %d \n", *((long*)(sqlda_sli->V[1])) );
printf( " v_long: %d \n", v_long );
v_float = *((float*)(sqlda_sli->V[2]));
printf( "sli float: %f \n", *((float*)(sqlda_sli->V[2])) );
printf( " v_float: %f \n", v_float );
v_double = *((double*)(sqlda_sli->V[3]));
printf( "sli double: %e \n", *((double*)(sqlda_sli->V[3])) );
printf( " v_double: %e \n", v_double );
printf( "sli double: %f \n", *((double*)(sqlda_sli->V[3])) );
printf( " v_double: %f \n", v_double );
if (1.111111111111111e111 == v_double ) {
printf("1.111111111111111e111 == v_double\n");
} else {
printf("WARNING: 1.111111111111111e111 != v_double\n");
}
/* Deallocate storage for SLIs, BVs, and SQLDAs */
/* Handle SLI deallocations */
for(i=1;i<sqlda_sli->F+1;i++)
{
free(sqlda_sli->V[i-1]);
free(sqlda_sli->I[i-1]);
/* Handle BV deallocations */
for(i=1;i<sqlda_bv->F+1;i++)
{
free(sqlda_bv->V[i-1]);
free(sqlda_bv->I[i-1]);
/* Handle sqlda deallocations */
sqlclu(sqlda_bv);
sqlclu(sqlda_sli);
EXEC SQL CLOSE curs1;
return 0;
}
void sql_error(char *msg)
{
cout << endl << msg << endl;
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
oraca.orastxt.orastxtc[oraca.orastxt.orastxtl] = '\0';
oraca.orasfnm.orasfnmc[oraca.orasfnm.orasfnml] = '\0';
cout << sqlca.sqlerrm.sqlerrmc << endl;
cout << "in " << oraca.orastxt.orastxtc << endl;
cout << "on line " << oraca.oraslnr << " of " <<
oraca.orasfnm.orasfnmc
<< endl << endl;
/* Disable ORACLE error checking to avoid an infinite loop
* should another error occur within this routine.
*/
![]() |
![]() |