Exception.ToString() failed
Hi!
When I run my code, I get the following message:
"Unhandled Exception:
Exception.ToString() failed."
The connection to server is o"k. The message appears only when I try to execute the select statement. I think it happens when I want to put the selected values to the variables. How should I change the code?
My code:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>
static text *username = (text *) "myuser";
static text *password = (text *) "mypass";
static text *server = (text *) "myserver";
/* Define SQL statements to be used in the program. */
static text *course_count = (text *)"SELECT COUNT(*) FROM COURSE";
static text *course_ten = (text *)"SELECT course_no, description, cost FROM course WHERE course_no = 10";
static text *course_low = (text *)"SELECT course_no, description, cost FROM course WHERE course_no < 100";
static OCIEnv *envhp; // The Env handle is the most basic for Oracle
static OCIError *errhp; // And we use the error handle to retrieve any err info
struct OCIEnv { };
struct OCIError { };
/* Function prototypes for locally defined functions but with comments */
static void checkerr(OCIError *errhp, sword status);
static void cleanup(/*_ void _*/);
static void myfflush(/*_ void _*/);
int main(int argc, char *argv[]);
static sword status;
int main(int argc, char *argv[])
{
sword ccount;
sword cno;
sword ccost;
sb1 descr_buf[51];
OCISession *authp = (OCISession *) 0;
OCIServer *srvhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIDefine *defnp = (OCIDefine *) 0;
OCIDefine *defnp1 = (OCIDefine *) 0;
OCIDefine *defnp2 = (OCIDefine *) 0;
OCIDefine *defnp3 = (OCIDefine *) 0;
(void) OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0,
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0 );
(void) OCIEnvInit( (OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0,
(dvoid **) 0 );
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,
(size_t) 0, (dvoid **) 0);
/* server contexts */
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,
(size_t) 0, (dvoid **) 0);
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0);
(void) OCIServerAttach( srvhp, errhp, (text *)server, strlen((char *)server), 0);
/* set attribute server context in the service context */
(void) OCIAttrSet( (dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp,
(ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp);
(void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);
(void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
(dvoid *) username, (ub4) strlen((char *)username),
(ub4) OCI_ATTR_USERNAME, errhp);
(void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
(dvoid *) password, (ub4) strlen((char *)password),
(ub4) OCI_ATTR_PASSWORD, errhp);
checkerr(errhp, OCISessionBegin ( svchp, errhp, authp, OCI_CRED_RDBMS,
(ub4) OCI_DEFAULT));
(void) OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *) authp, (ub4) 0,
(ub4) OCI_ATTR_SESSION, errhp);
/* Prepare an SQL statement */
// We begin by allocating a handle for our SQL statement(s)
checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp,
OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
// Once we have the handle, the next step is always to prepare
// the statement
checkerr(errhp, OCIStmtPrepare(stmthp, errhp, course_count,
(ub4) strlen((char *) course_count),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
/* bind the input variable */
checkerr(errhp, OCIDefineByPos(stmthp, &defnp, errhp, 1, (dvoid *) &ccount,
(sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
/* execute and fetch */
// Be sure and check the return status and account for any possibilities
// like no tuples returned, a single tuple returned, or multiple tuples
// returned.
if (status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
{
if (status == OCI_NO_DATA) {
fprintf(stderr, "No data on select count(*) from course\n");
} else
{
checkerr(errhp, status);
cleanup();
return OCI_ERROR;
}
}
printf("Course count: %d\n", ccount);
// The next example will execute an SQL statement with more than one
// projected attributes, but still with only a single tuple returned.
// We begin by preparing the statement. Note that we can reuse the
// statement handle.
checkerr(errhp, OCIStmtPrepare(stmthp, errhp, course_ten,
(ub4) strlen((char *) course_ten),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
/* bind the input variables */
checkerr(errhp, OCIDefineByPos(stmthp, &defnp1, errhp, 1, (dvoid *) &cno,
(sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
checkerr(errhp, OCIDefineByPos(stmthp, &defnp2, errhp, 2, (dvoid *) descr_buf,
(sword) sizeof(descr_buf), SQLT_STR, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
checkerr(errhp, OCIDefineByPos(stmthp, &defnp3, errhp, 3, (dvoid *) &ccost,
(sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
if (status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
{
if (status == OCI_NO_DATA) {
fprintf(stderr, "No data on select from course\n");
} else
{
checkerr(errhp, status);
cleanup();
return OCI_ERROR;
}
}
printf("Course number, descr, cost: %d | %s | %d\n", cno, descr_buf, ccost);
// Final example demonstrates fetching multiple tuples as the result
// of an SQL query
// We begin by preparing the statement. Note that we can reuse the
// statement handle.
checkerr(errhp, OCIStmtPrepare(stmthp, errhp, course_low,
(ub4) strlen((char *) course_low),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
/* bind the input variables */
checkerr(errhp, OCIDefineByPos(stmthp, &defnp1, errhp, 1, (dvoid *) &cno,
(sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
checkerr(errhp, OCIDefineByPos(stmthp, &defnp2, errhp, 2, (dvoid *) descr_buf,
(sword) sizeof(descr_buf), SQLT_STR, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
checkerr(errhp, OCIDefineByPos(stmthp, &defnp3, errhp, 3, (dvoid *) &ccost,
(sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT));
// Note on the stmt execution that we set the fourth parameter to zero
// to defer any fetch until the loop below.
if (status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 0, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT))
{
if (status == OCI_NO_DATA) {
fprintf(stderr, "No data on select from course\n");
} else
{
checkerr(errhp, status);
cleanup();
return OCI_ERROR;
}
}
while ((status = OCIStmtFetch2(stmthp, errhp, (ub4) 1, (ub2) OCI_FETCH_NEXT,
(sb4) 0, OCI_DEFAULT)) == OCI_SUCCESS) {
printf("Course number, descr, cost: %d | %s | %d\n",
cno, descr_buf, ccost);
}
if (status == OCI_NO_DATA) {
fprintf(stderr, "No data on select from course\n");
} else
{
checkerr(errhp, status);
cleanup();
return OCI_ERROR;
}
}
void checkerr(OCIError *errhp, sword status)
{
text errbuf[512];
sb4 errcode = 0;
switch (status)
{
case OCI_SUCCESS:
break;
case OCI_SUCCESS_WITH_INFO:
(void) printf("Error - OCI_SUCCESS_WITH_INFO\n");
break;
case OCI_NEED_DATA:
(void) printf("Error - OCI_NEED_DATA\n");
break;
case OCI_NO_DATA:
(void) printf("Error - OCI_NODATA\n");
break;
case OCI_ERROR:
(void) OCIErrorGet((dvoid *)errhp, (ub4) 1, (text *) NULL, &errcode,
errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
(void) printf("Error - %.*s\n", 512, errbuf);
break;
case OCI_INVALID_HANDLE:
(void) printf("Error - OCI_INVALID_HANDLE\n");
break;
case OCI_STILL_EXECUTING:
(void) printf("Error - OCI_STILL_EXECUTE\n");
break;
case OCI_CONTINUE:
(void) printf("Error - OCI_CONTINUE\n");
break;
default:
break;
}
}
/*
* Exit program with an exit code.
*/
void cleanup()
{
if (envhp)
(void) OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV);
return;
}
void myfflush()
{
eb1 buf[50];
fgets((char *) buf, 50, stdin);
}