#include #include #include #include static text *username = (text *) "STUDENT"; static text *password = (text *) "LEARN"; /* 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 /* 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(argc, argv) 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 *)"", strlen(""), 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(errhp, status) 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); }