Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.misc -> Re: oci c unix
Below is a C++ program I've written that I usually use as a starting
point for my OCI programs. It should be easy to convert to C if you
are out of luck and have to use C. To execute a stored procedure
instead of straight SQL, use a SQL string like this:
string sSQL = "BEGIN mypackage.myprocedure(:param1,:param2); END;";
First, here's how to compile the code (using GCC on Solaris): g++ -O3 -D_REENTRANT -Wall -D__EXTENSIONS__ -o ocitest ocitest.cpp \
-L/app/oracle/product/8.1.6/lib \ -I/app/oracle/product/8.1.6/rdbms/demo \ -I/app/oracle/product/8.1.6/rdbms/public \ -I/app/oracle/product/8.1.6/network/public -lclntsh \ -lresolv -lnsl -lm -lpthread
The code:
//---------------- ocitest.h -------------------------#include <string>
using std::string;
struct OCIException
{
string message;
OCIException(string mess) : message(mess)
{
}
};
class OCITest
{
private:
string username; string password; string database; OCIEnv * environment; OCIServer * server; OCIError * error; OCISvcCtx * serviceContext; OCIBind * bindHandle; dvoid * temp;
void checkerr(OCIError * error, sword ret); void bindString(short,char*,sword,sb2*,OCIStmt *); void bindShort(short,short *,sb2*,OCIStmt *); void bindLong(short,long *,sb2*,OCIStmt *); void bindDouble(short,double *,sb2*,OCIStmt *);
public:
OCITest(const string&,const string&,const string&);
void connect();
void select(); void update(); void insert();
//---------------- ocitest.cpp -------------------------#include "ocitest.h"
OCITest::OCITest(const string& u,const string& p,const string& d)
: username(u), password(p),database(d)
void OCITest::connect()
{
OCIEnvCreate((OCIEnv **)&environment, OCI_DEFAULT, 0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, (dvoid (*)(dvoid *, dvoid *)) 0,0,0); checkerr(error,
checkerr(error,
OCILogon(environment,error,&serviceContext,(unsigned char*)
username.c_str(),strlen((const char*) username.c_str()),(unsigned
char*) password.c_str(),strlen((const char*) password.c_str()),
(unsigned char*) database.c_str(),strlen((const char*)
database.c_str())));
}
void OCITest::disconnect()
{
checkerr(error,
OCILogoff(serviceContext,error));
checkerr(error,
OCIHandleFree((dvoid *) error, OCI_HTYPE_ERROR));
if (environment)
{
checkerr(error,
OCIHandleFree((dvoid *) environment, OCI_HTYPE_ENV));
}
}
void OCITest::insert()
{
//Step 1: Allocate handle for SQL statement
OCIStmt * sqlStatement;
checkerr(error,
OCIHandleAlloc((dvoid *) environment,(dvoid **)
&sqlStatement,OCI_HTYPE_STMT,100,(dvoid **) &temp));
//Step 2: Prepare SQL statement
string sSQL = "insert into testtable (name,age) values (:1,2)";
checkerr(error,
OCIStmtPrepare(sqlStatement,error,(unsigned char *) const_cast<char
*>(sSQL.c_str()),strlen(sSQL.c_str()),OCI_NTV_SYNTAX,OCI_DEFAULT));
//Step 3 (optional): Bind variables in SQL
char * param="due";
signed short nullIndicator=1; //1==NULL
bindString(1, param,sizeof(param),&nullIndicator,sqlStatement);
//Step 4: Execute SQL
ret = OCIStmtExecute(serviceContext,sqlStatement,error,(ub4) 1,(ub4)
0,(CONST OCISnapshot *) NULL,(OCISnapshot *) NULL,OCI_DEFAULT);
checkerr(error, ret);
//Step 5: Free the SQL statement handle
checkerr(error,
OCIHandleFree((dvoid *) sqlStatement, OCI_HTYPE_STMT));
}
void OCITest::update()
{
//Step 1: Allocate handle for SQL statement
OCIStmt * sqlStatement;
checkerr(error,
OCIHandleAlloc((dvoid *) environment,(dvoid **)
&sqlStatement,OCI_HTYPE_STMT,100,(dvoid **) &temp));
//Step 2: Prepare SQL statement
string sSQL = "update testtable set name = :1 where age=1";
checkerr(error,
OCIStmtPrepare(sqlStatement,error,(unsigned char *) const_cast<char
*>(sSQL.c_str()),strlen(sSQL.c_str()),OCI_NTV_SYNTAX,OCI_DEFAULT));
//Step 3 (optional): Bind variables in SQL
char * param="uno";
signed short nullIndicator=0; //1==NULL
bindString(1, param,sizeof(param),&nullIndicator,sqlStatement);
//Step 4: Execute SQL
ret = OCIStmtExecute(serviceContext,sqlStatement,error,(ub4) 1,(ub4)
0,(CONST OCISnapshot *) NULL,(OCISnapshot *) NULL,OCI_DEFAULT);
checkerr(error, ret);
//Step 5: Free the SQL statement handle
checkerr(error,
OCIHandleFree((dvoid *) sqlStatement, OCI_HTYPE_STMT));
}
void OCITest::dodelete()
{
//Step 1: Allocate handle for SQL statement
OCIStmt * sqlStatement;
checkerr(error,
OCIHandleAlloc((dvoid *) environment,(dvoid **)
&sqlStatement,OCI_HTYPE_STMT,100,(dvoid **) &temp));
//Step 2: Prepare SQL statement
string sSQL = "delete from testtable where name = :1";
checkerr(error,
OCIStmtPrepare(sqlStatement,error,(unsigned char *) const_cast<char
*>(sSQL.c_str()),strlen(sSQL.c_str()),OCI_NTV_SYNTAX,OCI_DEFAULT));
//Step 3 (optional): Bind variables in SQL
char * param="uno";
signed short nullIndicator=0; //1==NULL
bindString(1, param,sizeof(param),&nullIndicator,sqlStatement);
//Step 4: Execute SQL
ret = OCIStmtExecute(serviceContext,sqlStatement,error,(ub4) 1,(ub4)
0,(CONST OCISnapshot *) NULL,(OCISnapshot *) NULL,OCI_DEFAULT);
checkerr(error, ret);
//Step 5: Free the SQL statement handle
checkerr(error,
OCIHandleFree((dvoid *) sqlStatement, OCI_HTYPE_STMT));
}
void OCITest::select()
{
//Step 1: Allocate handle for SQL statement
OCIStmt * sqlStatement;
checkerr(error,
OCIHandleAlloc((dvoid *) environment,(dvoid **)
&sqlStatement,OCI_HTYPE_STMT,100,(dvoid **) &temp));
//Step 2: Prepare SQL statement
string sSQL = "select name,age from testtable where name <> :1";
checkerr(error,
OCIStmtPrepare(sqlStatement,error,(unsigned char *) const_cast<char
*>(sSQL.c_str()),strlen(sSQL.c_str()),OCI_NTV_SYNTAX,OCI_DEFAULT));
//Step 3 (optional): Bind variables in SQL
char * param="E";
signed short nullIndicator=0; //1==NULL
bindString(1, param,sizeof(param),&nullIndicator,sqlStatement);
//Step 4: Define Output Variables
OCIDefine * defnp = (OCIDefine *) 0;
short name_length=20;
char name[name_length];
checkerr(error,
OCIDefineByPos(sqlStatement, &defnp, error, 1, (dvoid *) name,
name_length+1, SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0,
OCI_DEFAULT));
int age;
checkerr(error,
OCIDefineByPos(sqlStatement, &defnp, error, 2, (dvoid *) &age, (sb4)
sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4)
OCI_DEFAULT));
//Step 5: Execute query
ret = OCIStmtExecute(serviceContext,sqlStatement,error,(ub4) 1,(ub4)
0,(CONST OCISnapshot *) NULL,(OCISnapshot *) NULL,OCI_DEFAULT);
if (ret != OCI_NO_DATA && ret != OCI_SUCCESS_WITH_INFO)
{
checkerr(error, ret);
cout << "Name:" << name << ", Age:" << age << endl;
}
else
cout << "No data or info." << endl;
//Step 6: Fetch all the data
while ((ret = OCIStmtFetch(sqlStatement, error, (ub4) 1, (ub4)
OCI_FETCH_NEXT, (ub4) OCI_DEFAULT)) == OCI_SUCCESS || ret ==
OCI_SUCCESS_WITH_INFO)
{
cout << "Name:" << name << ", Age:" << age << endl;
}
//Step 7: Free the SQL statement handle
checkerr(error,
OCIHandleFree((dvoid *) sqlStatement, OCI_HTYPE_STMT));
}
inline void OCITest::bindShort(short position,short * value,sb2 *
nullInd,OCIStmt * sqlStatement)
{
int returnCode = OCIBindByPos(sqlStatement,&bindHandle,error,position,
(ub1 *) value,(sword) sizeof(*value),SQLT_INT, nullInd,(ub2 *) 0,(ub2) 0,(ub4) 0,(ub4 *)0,OCI_DEFAULT);
inline void OCITest::bindLong(short position,long * value,sb2 *
nullInd,OCIStmt * sqlStatement)
{
int returnCode = OCIBindByPos(sqlStatement,&bindHandle,error,position,
(ub1 *) value,(sword) sizeof(*value),SQLT_INT, nullInd,(ub2 *) 0,(ub2) 0,(ub4) 0,(ub4 *)0,OCI_DEFAULT);
inline void OCITest::bindString(short position,char * value,sword
size,sb2 * nullInd,OCIStmt * sqlStatement)
{
int returnCode = OCIBindByPos(sqlStatement,&bindHandle,error,position,
(ub1 *) value,size,SQLT_STR, nullInd,(ub2 *) 0,(ub2) 0,(ub4) 0,(ub4 *)0,OCI_DEFAULT);
inline void OCITest::bindDouble(short position,double * value,sb2 *
nullInd,OCIStmt * sqlStatement)
{
int returnCode = OCIBindByPos(sqlStatement,&bindHandle,error,position,
(ub1 *) value,(sword) sizeof(*value),SQLT_FLT, nullInd,(ub2 *) 0,(ub2) 0,(ub4) 0,(ub4 *)0,OCI_DEFAULT);
void OCITest::checkerr(OCIError * error, sword ret)
{
text errbuf[512];
ub4 errcode;
switch (ret)
{
case OCI_SUCCESS:
break;
case OCI_SUCCESS_WITH_INFO:
throw OCIException("OCIError - OCI_SUCCESS_WITH_INFO\n"); break; case OCI_NEED_DATA: throw OCIException("OCIError - OCI_NEED_DATA\n"); break; case OCI_NO_DATA: throw OCIException("OCIError - OCI_NODATA\n"); break;
ostrstream oss; oss << "OCIError - " << errbuf << "\n" << ends; throw OCIException(oss.str()); break;
throw OCIException("OCIError - OCI_INVALID_HANDLE\n"); break; case OCI_STILL_EXECUTING: throw OCIException("OCIError - OCI_STILL_EXECUTE\n"); break; default: break;
int main()
{
OCITest * myOCITest = new OCITest("username","password","SID");
myOCITest->connect();
cout << "Connected!" << endl;
myOCITest->select(); myOCITest->insert(); myOCITest->update(); myOCITest->dodelete(); myOCITest->disconnect();
![]() |
![]() |