Oracle Call Interface - Linux/Unix下Oracle数据库访问接口程序

来源:互联网 发布:2017云计算龙头股 编辑:程序博客网 时间:2024/05/17 04:14

Oracle Call Interface

 

 Linux/Unix下的Oracle数据库访问接口程序 很好!很强大!充分满足你绝大部分需要!

 

本接口程序用C++完成,通行于Linux/Unix平台,尤其适合服务器端使用。

包括:OCI.h OCI.cpp test.h test.cpp makefile 共4个文件(完整代码),

建议把所有代码copy到 Ultra Edit里面去看,并且把tab设置为4,这样就很工整!

有一定基础的开发人员绝对可看懂。

版权声明:如在别的任何网站有看到该文章,如果未注明作者为欧昕,均为抄袭。

 

【OCI.h】

#ifndef _OCI_H
#define _OCI_H

#include <iostream>
#include <fstream>
#include <list>
#include <map>
#include <vector>
#include <memory>
#include <string>
#include <limits>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <pthread.h>
#include <stdarg.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <termios.h>
#include <fcntl.h>
#include <istream>

#include "oci.h"
#include "oratypes.h"
#include "ocidfn.h"
#include "ocidem.h"
#include "ociapr.h"

const   char* const NULL_STRING = "";
const   int NULL_NUMBER = 0;
const int MAX_ERRMSG_LENGTH = 1024;
const int MAX_STRING_LENGTH = 1024;

class OCIException;
class OCIDatabase;
class OCIQuery;
class OCIField;
class OCIParam;

class OCIException
{
int   errNo;
text errInfo[MAX_ERRMSG_LENGTH+1];
public:
   OCIException(OCIError* herr);
   OCIException(const char* msg);
   ~OCIException();
   char *getErrInfo() const;
   int   getErrNo() const;
};


class OCIDatabase
{
char Tns[50];
char Usr[10];
char Pwd[10];
OCIEnv *hEnv;
OCIServer *hSvr;
OCIError *hDBErr;
bool active;
friend class OCIQuery;
public:
   OCIDatabase();
   ~OCIDatabase();
   void setLogin(const char* tns,const char* usr,const char* pwd) ;
   int connect();
   void disConnect();
};

class OCIField
{
friend class OCIQuery;
OCIQuery *ParentQuery;   //指向该Field所属于的Query
ub1 StrBuf[MAX_STRING_LENGTH];//用于保存转换为字符串后的返回值
ub1 *DataBuf;    //在分析字段时候获得空间max(该列的最大长度,MAX_STRING_VALUE_LENGTH), 在Destructor中释放
sb2 *DataIndicator;   //在defineByPos中使用,用于在fetch时察看是否有字段值返回,字段值是否被截断;valueIsNULL,isTruncated根据此值获得结果
OCIDefine *Dfn;   //用于读取列信息
char *Name;     //字段名称
long Size;     //数据长度
long Type;     //数据类型(INT_TYPE,FLOAT_TYPE,DATE_TYPE,STRING_TYPE,ROWID_TYPE)
int Precision;    //数值总长度
int Scale;     //数值中小数点个数
public:
   OCIField();
   ~OCIField();
   int   isNULL();
   char* asString();
   int   asInteger();
   float asFloat();
   char asChar();
   char* asDateTimeString(); //按HH:MM:DD HH24:MI:SS格式读取
   void getDateTime(int &year, int &month, int &day, int &hour, int &minute, int &second);
};

class OCIQuery
{
friend class OCIField;
public:
OCISession *hUser;
OCIStmt   *hStmt;    //用于分析sql语句的handle
OCISvcCtx *hSvc;    //服务
OCIError *hErr;    //错误处理
sword ErrorNo;     //错误号
OCIDatabase *db;    //父DataBase
OCIField *FieldList;   //在内部保存的所有字段信息
bool Opened;     //数据集是否打开
int FieldCount;    //字段个数
bool Eof;      //已到最后一个记录
char *Sql;
ub2 SqlType;
unsigned Fetched;
unsigned CurrRow;
unsigned TotalRowsFetched;
bool InUse;     //使用中
public:
   OCIQuery();
   ~OCIQuery();
   void setDB(OCIDatabase *oradb);
   void close();
   void setSql(char *s);
   char *getSql();
   void open();
   int next();
   int exec();
   int commit();
   int rollBack();
   int getAffected() {return TotalRowsFetched;};
   int getFieldCount();
   OCIField* field(int index);
   OCIField* fieldByName(char *fieldName);
   void getFieldsDef();
   void checkError();
   void sign(){InUse = true;}
   void release(){InUse = false;};
};

#endif
【OCI.cpp】

#include "OCI.h"

//比较2个字符串是否相同(不考虑大小写)
int inline CompareStrNoCase(char *ori, char *des)
{
int j,nLen1,nLen2;
int sameChar;
nLen1 = strlen(ori);
nLen2 = strlen(des);
if (nLen1!=nLen2) return 0;
sameChar = 1;
for (j=0; j<nLen1; j++)
   sameChar = sameChar && (toupper(ori[j]) == toupper(des[j]));
return sameChar;
}

OCIException::OCIException(OCIError* herr)
{
if (herr != NULL)
{
   (void)OCIErrorGet ((dvoid*) herr, (ub4) 1, (text *) NULL, &errNo,
     errInfo, (ub4)sizeof(errInfo)-1, (ub4) OCI_HTYPE_ERROR);
}
}

OCIException::OCIException(const char* msg)
{
if (msg != NULL)
{
   strcpy((char*)errInfo,msg);
}
}

OCIException::~OCIException()
{
}

char *OCIException::getErrInfo() const
{
return((char*)errInfo);
}

int   OCIException::getErrNo() const
{
return errNo;
}

OCIDatabase::OCIDatabase()
{
memset(Tns,0,sizeof(Tns));
memset(Usr,0,sizeof(Usr));
memset(Pwd,0,sizeof(Pwd));
active = false;
sword errorNo;
errorNo = OCIInitialize((ub4) OCI_DEFAULT,0, 0,0,0);
errorNo = errorNo + OCIEnvInit((OCIEnv **) &hEnv, (ub4) OCI_DEFAULT,(size_t) 0, (dvoid **) 0);
errorNo = errorNo + OCIHandleAlloc((dvoid*) hEnv, (dvoid **) &hDBErr,(ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0);
errorNo = errorNo + OCIHandleAlloc((dvoid*) hEnv, (dvoid **) &hSvr,(ub4) OCI_HTYPE_SERVER,(size_t) 0, (dvoid **) 0);
if (errorNo != OCI_SUCCESS)throw OCIException(hDBErr);
}

OCIDatabase::~OCIDatabase()
{
if (active) OCIServerDetach(hSvr, hDBErr, OCI_DEFAULT);
OCIHandleFree(hSvr, OCI_HTYPE_SERVER);
OCIHandleFree(hDBErr,OCI_HTYPE_ERROR);
OCIHandleFree(hEnv,OCI_HTYPE_ENV);
}

void OCIDatabase::setLogin(const char* tns,const char* usr,const char* pwd)
{
memset(Tns,0,sizeof(Tns));
strcpy(Tns,tns);
memset(Usr,0,sizeof(Usr));
strcpy(Usr,usr);
memset(Pwd,0,sizeof(Pwd));
strcpy(Pwd,pwd);
}

int OCIDatabase::connect()
{
sword errorNo = OCIServerAttach(hSvr, hDBErr, (text*)Tns, strlen(Tns), 0);
if (errorNo != OCI_SUCCESS)
{
   throw OCIException(hDBErr);
   return 0;
}
active = true;
return 1;
}

void OCIDatabase::disConnect()
{
sword errorNo = OCIServerDetach(hSvr, hDBErr, OCI_DEFAULT);
if (errorNo != OCI_SUCCESS) throw OCIException(hDBErr);
active = false;
}

/*********** field Implementation*************/
OCIField::OCIField()
{
Name = NULL;
Dfn = (OCIDefine *) 0; ;
DataBuf = NULL;
DataIndicator = NULL;
ParentQuery = NULL;
Size = 0;
Precision = 0;
Scale = 0;
Size = 0;
};

OCIField::~OCIField()
{
if (DataIndicator != NULL)
   delete[] DataIndicator;
if (Name != NULL)
   delete[] Name;
if (DataBuf != NULL)
   delete[] DataBuf;
}

char* OCIField::asString()
{
memset(StrBuf,0,sizeof(StrBuf));
if (isNULL())
{
   sprintf((char*)StrBuf,"%s", NULL_STRING);
   return (char*)StrBuf;
}
switch (Type)
{
   case DATE_TYPE:
    int year, month, day, hour, minute, second;
    getDateTime(year, month, day, hour, minute, second);
    sprintf((char*)StrBuf,"%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute,second);
    return (char*)StrBuf;
   case INT_TYPE:
   case FLOAT_TYPE:
    memcpy(StrBuf,DataBuf+(Size+1)*ParentQuery->CurrRow,Size);
    return (char*)StrBuf;
   case STRING_TYPE:
    memcpy(StrBuf,DataBuf+(Size+1)*ParentQuery->CurrRow,Size);
    return (char*)StrBuf;
   default:
    throw OCIException("Unknown DataType");
}
}

int OCIField::asInteger()
{
return(atoi(asString()));
}
float OCIField::asFloat()
{
return(atof(asString()));
}

char OCIField::asChar()
{
return asString()[0];
}

int OCIField::isNULL()
{
return (DataIndicator[ParentQuery->CurrRow]==-1);
}


char* OCIField::asDateTimeString()
{
int year, month, day, hour, minute, second;
if (Type != DATE_TYPE)
   throw OCIException("Can't Convert UnDataTime Type to DataTime Type");
else
{
   getDateTime(year, month, day, hour, minute, second);
   if (year == 0)
    sprintf((char*)StrBuf,"%s",NULL_STRING);
   else
    sprintf((char*)StrBuf,"%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute,second);
   return (char*)StrBuf;
}
}

void OCIField::getDateTime(int &year, int &month, int &day, int &hour, int &minute, int &second)
{
if (isNULL())
{
   year = 0;
   month = 0;
   day = 0;
   hour = 0;
   minute = 0;
   second = 0;
   return;
}
unsigned char cc,yy,mm,dd,hh,mi,ss;
ub1 *data;
data = DataBuf + 7 * (ParentQuery->CurrRow);
cc=data[0];
yy=data[1];
mm=data[2];
dd=data[3];
hh=data[4]-1;
mi=data[5]-1;
ss=data[6]-1;
cc=(unsigned char)abs(cc-100);
yy=(unsigned char)abs(yy-100);
year = (unsigned int)cc*100 + (unsigned int) yy;
month = mm;
day = dd;
hour = hh;
minute = mi;
second = ss;
}

OCIQuery::OCIQuery()
{
InUse = false;
Fetched = 0;
CurrRow = 0;
TotalRowsFetched = 0;
Eof = false;
FieldCount = 0;
Sql = NULL;
FieldList = NULL;
}

void OCIQuery::setDB(OCIDatabase *oradb)
{
if (!oradb->active) throw OCIException("Init Query Failure,DataBase Is Not Active");
InUse = false;
Fetched = 0;
CurrRow = 0;
TotalRowsFetched = 0;
Eof = false;
db = oradb;
FieldCount = 0;
Sql = NULL;
FieldList = NULL;
ErrorNo = OCIHandleAlloc(db->hEnv, (dvoid **) &hUser,(ub4) OCI_HTYPE_SESSION,(size_t) 0, (dvoid **) 0);
checkError();
ErrorNo = OCIHandleAlloc(db->hEnv, (dvoid **) &hErr,(ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0);
checkError();
ErrorNo = OCIHandleAlloc(db->hEnv, (dvoid **)&hStmt, OCI_HTYPE_STMT, 0, 0);
checkError();
ErrorNo = OCIHandleAlloc(db->hEnv, (dvoid **)&hSvc, OCI_HTYPE_SVCCTX,0, 0);
checkError();
OCIAttrSet (hSvc, OCI_HTYPE_SVCCTX, db->hSvr, 0, OCI_ATTR_SERVER, hErr);
OCIAttrSet(hUser, OCI_HTYPE_SESSION, db->Usr, strlen(db->Usr),OCI_ATTR_USERNAME, hErr);
OCIAttrSet(hUser, OCI_HTYPE_SESSION, db->Pwd, strlen(db->Pwd),OCI_ATTR_PASSWORD, hErr);
OCIAttrSet(hSvc, OCI_HTYPE_SVCCTX, hUser, 0, OCI_ATTR_SESSION, hErr);
OCISessionBegin (hSvc, hErr, hUser, OCI_CRED_RDBMS, OCI_DEFAULT);
}

OCIQuery::~OCIQuery()
{
if (Sql != NULL) delete[] Sql;
if (FieldCount >0) delete[] FieldList;
OCISessionEnd (hSvc, hErr, hUser, OCI_DEFAULT);
OCIHandleFree(hStmt, OCI_HTYPE_STMT);
OCIHandleFree(hSvc, OCI_HTYPE_SVCCTX);
OCIHandleFree(hUser,OCI_HTYPE_SESSION);
OCIHandleFree(hErr,OCI_HTYPE_ERROR);
}

void OCIQuery::close()
{
if (Sql != NULL)
{
   delete[] Sql;
   Sql = NULL;
}
if (FieldCount > 0)
{
   delete[] FieldList;
   FieldList = NULL;
}

FieldCount = 0;
Fetched = 0;
CurrRow = 0;
TotalRowsFetched = 0;
}

int OCIQuery::commit()
{
ErrorNo = OCITransCommit(hSvc, hErr, OCI_DEFAULT);
checkError();
return (ErrorNo == OCI_SUCCESS);
}

int OCIQuery::rollBack()
{
int exeSuccess = 0;
ErrorNo = OCITransRollback(hSvc, hErr, OCI_DEFAULT);
if (ErrorNo == OCI_SUCCESS)
   exeSuccess = 1;
else
   checkError();
return exeSuccess;
}

void OCIQuery::getFieldsDef()
{
char temp[20];
memset(temp,0,sizeof(temp));
OCIField *pCurrField;
void* param = (void *)0;
ub4 ColumnCount;         //列数目
text* ColumnName;    //字段名称
ub4 ColumnNameLength,j; //字段名称长度 unsigned int
ub2 InnerDataSize;    //数据长度 unsigned short
ub2 InnerDataType;    //Oracle 内部数据类型 signed short
ub2 InnerPrecision;   //包括小数点的总位数
sb1 InnerScale;    //小数点个数
ub1 InnerIsNULL;    //是否允许为空值

if(SqlType==OCI_STMT_SELECT)
   ErrorNo = OCIStmtExecute(hSvc, hStmt, hErr, (ub4)0, (ub4)0, 0, 0, OCI_DEFAULT);
else
   ErrorNo = OCIStmtExecute(hSvc, hStmt, hErr, (ub4)1, (ub4)0, 0, 0, OCI_DEFAULT);
checkError();

ErrorNo = OCIAttrGet((dvoid*)hStmt, (ub4)OCI_HTYPE_STMT, (dvoid*)&ColumnCount, (ub4 *) 0, (ub4)OCI_ATTR_PARAM_COUNT, hErr);
checkError();

if (FieldCount >0) delete[] FieldList;
FieldList = new OCIField[ColumnCount];
FieldCount = ColumnCount;

ub4 k;
for(k=1; k<=ColumnCount ; k ++)
{
   ErrorNo = OCIParamGet(hStmt, OCI_HTYPE_STMT, hErr, (dvoid **)&param, k);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid**)&ColumnName,(ub4 *)&ColumnNameLength, OCI_ATTR_NAME, hErr);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&InnerDataSize, (ub4 *)0, OCI_ATTR_DATA_SIZE, hErr);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&InnerPrecision, (ub4 *)0, OCI_ATTR_PRECISION, hErr);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&InnerScale, (ub4 *)0, OCI_ATTR_SCALE, hErr);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&InnerIsNULL, (ub4 *)0, OCI_ATTR_IS_NULL, hErr);
   checkError();
   ErrorNo = OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&InnerDataType, (ub4 *)0, OCI_ATTR_DATA_TYPE, hErr);
   checkError();
   pCurrField = &FieldList[k-1];

   pCurrField->Name = new char[ColumnNameLength+1];
   if (pCurrField->Name == NULL)
    throw OCIException("field Name Is Null");
   
   for (j=0; j<ColumnNameLength; j++)
    pCurrField->Name[j] = ColumnName[j];
   pCurrField->Name[ColumnNameLength] = '/0';
   pCurrField->Type = InnerDataType;
   pCurrField->ParentQuery = this;
   pCurrField->DataIndicator = new sb2[1];

   switch (InnerDataType)
   {
   case SQLT_NUM:
   {
    if (! InnerDataSize)
     pCurrField->Size = 255;
    else
     pCurrField->Size = InnerDataSize;
    pCurrField->Precision = InnerPrecision;
    pCurrField->Scale = InnerScale;
    pCurrField->DataBuf = new ub1[pCurrField->Size+1];
    if (InnerScale == 0)
     pCurrField->Type = INT_TYPE;
    else
     pCurrField->Type = FLOAT_TYPE;
    ErrorNo = OCIDefineByPos(hStmt, &(pCurrField->Dfn), hErr, k,
     (dvoid*)pCurrField->DataBuf, pCurrField->Size + 1, SQLT_STR,
     (dvoid*)pCurrField->DataIndicator, (ub2*)0 , (ub2*) 0, OCI_DEFAULT);
    checkError();
    break;
   }
   case SQLT_DAT:
   {
    pCurrField->Type = DATE_TYPE;
    pCurrField->Size = 7;
    pCurrField->DataBuf = new ub1[pCurrField->Size];
    ErrorNo = OCIDefineByPos(hStmt, &(pCurrField->Dfn), hErr, k,
     pCurrField->DataBuf, 7, SQLT_DAT,
     (dvoid*)pCurrField->DataIndicator, (ub2*)0, (ub2*) 0, OCI_DEFAULT);
    checkError();
    break;
   }
   case SQLT_CHR: case SQLT_AFC:
   {
    pCurrField->Type = STRING_TYPE;
    pCurrField->Size = InnerDataSize;
    pCurrField->DataBuf = new ub1[pCurrField->Size+1];
    ErrorNo = OCIDefineByPos(hStmt, &(pCurrField->Dfn), hErr, k,
     pCurrField->DataBuf, pCurrField->Size+1, SQLT_STR,
     (dvoid*)pCurrField->DataIndicator, (ub2*)0, (ub2*)0, OCI_DEFAULT);
    checkError();
    //ub2 csid = OCI_UCS2ID;
    //ub2 csid = OCI_UTF16ID;
    //ErrorNo = OCIAttrSet((dvoid *)(pCurrField->Dfn),OCI_HTYPE_DEFINE, (dvoid *)&csid,0,OCI_ATTR_CHARSET_ID,hErr);
    break;
   }
   case SQLT_RDD:
   {
    pCurrField->Type = ROWID_TYPE;
    pCurrField->Size = 18;
    pCurrField->DataBuf = new ub1[pCurrField->Size+1];
    ErrorNo = OCIDefineByPos(hStmt, &(pCurrField->Dfn), hErr, k,
     (dvoid*)pCurrField->DataBuf,
     pCurrField->Size+1, SQLT_STR,
     (dvoid*)pCurrField->DataIndicator, (ub2*) 0, (ub2*) 0, OCI_DEFAULT);
    checkError();
    break;
   }
   default:
    throw OCIException("UnKnown DataType When GetFieldDef()");
    break;
   }
}
}

void OCIQuery::setSql(char *s)
{
if (strlen(s) <= 0)
   throw OCIException("Can't Set Null Sql For Query");

if (Sql != NULL) delete[] Sql;
int nLen = strlen(s);
Sql = new char[nLen + 1];
if (Sql == NULL) throw OCIException("Sql Str Is Null");
strcpy(Sql,s);
Sql[nLen] = 0;

ErrorNo = OCIStmtPrepare(hStmt, hErr, (unsigned char *)Sql, strlen(Sql), OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
checkError();
ErrorNo = OCIAttrGet(hStmt, OCI_HTYPE_STMT, &(this->SqlType), 0, OCI_ATTR_STMT_TYPE, hErr);
checkError();
}

char *OCIQuery::getSql()
{
if (Sql!=NULL)
{
     return Sql;
}
else
     return NULL;
}

void OCIQuery::checkError()
{
if (ErrorNo != OCI_SUCCESS)
   throw OCIException(hErr);
}

int OCIQuery::exec()
{
sb4 errcode;
text errbuf[MAX_ERRMSG_LENGTH-1];
int exeResult = 0;
if (Sql == NULL) throw OCIException("Can't exec a Null Sq");
if (SqlType == OCI_STMT_SELECT) throw OCIException("Can't exec a Select Sql");
ErrorNo = OCIStmtExecute(hSvc, hStmt, hErr, (ub4)1, (ub4)0, 0, 0, OCI_DEFAULT);
OCIAttrGet((dvoid*)hStmt, OCI_HTYPE_STMT, (dvoid*)&TotalRowsFetched, (ub4 *)0, OCI_ATTR_ROW_COUNT, hErr);
if (ErrorNo == OCI_SUCCESS)
   exeResult = 1;
else if (ErrorNo == OCI_ERROR)
{
   OCIErrorGet(hErr, (ub4) 1, (text *) NULL, &errcode,
    errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
   if (errcode == 1405)
    exeResult = 1;
   else
    checkError();
}
else
   checkError();
return exeResult;
}

void OCIQuery::open()
{
if (Sql == NULL) throw OCIException("Can't open a Null Sql");
if (this->SqlType !=OCI_STMT_SELECT) throw OCIException("Can't open a No-Select Sql");
getFieldsDef();
Opened = true;
}

int OCIQuery::getFieldCount()
{
return FieldCount;
}

OCIField* OCIQuery::field(int i)
{
if (!Opened) throw OCIException("Can't Access field,Not Opened");
if ((i>=0) && (i<FieldCount))
   return &FieldList[i];
else
   throw OCIException("field Index Out Of Bound");
}

OCIField* OCIQuery::fieldByName(char *fieldName)
{
if (! Opened) throw OCIException("Can't Access field,Not Opened");
int i;
int found = 0;

for(i=0; i<FieldCount; i++)
{
   found = CompareStrNoCase(field(i)->Name,fieldName);
   if (found == 1) break;
}
if (found == 1)
   return &FieldList[i];
else
   throw OCIException("field Not Exist");
}

int OCIQuery::next()
{
int fCanFetch = 1; //当前记录指针的位置是否可以存取数据
int tmpFetchedAllRows;

sb4 errcode;
text errbuf[MAX_ERRMSG_LENGTH];
int exeResult = 1;

if (!Opened)
   throw OCIException("Can't next,Not Opened");
CurrRow ++ ;
if((CurrRow == Fetched) && (Fetched < 1))
   fCanFetch=0;
else if(CurrRow==Fetched || ! Fetched)
{
   ErrorNo = OCIStmtFetch(hStmt, hErr, (ub4)1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT);
   tmpFetchedAllRows = TotalRowsFetched;
   ErrorNo = OCIAttrGet((dvoid*)hStmt, OCI_HTYPE_STMT, (dvoid*)&TotalRowsFetched, (ub4 *)0, OCI_ATTR_ROW_COUNT, hErr);
   Fetched = TotalRowsFetched - tmpFetchedAllRows;
   if(Fetched)
   {
    fCanFetch=1;
    CurrRow=0;
   }
   else fCanFetch=0;

   if (ErrorNo == OCI_SUCCESS)
    exeResult = 1;
   else if (ErrorNo == OCI_NO_DATA)
    exeResult = 0;
   else if (ErrorNo == OCI_ERROR) //以下允许返回空列(1405),修正:不可以返回被截断的列(1406)
   {
    OCIErrorGet (hErr, (ub4) 1, (text *) NULL, &errcode,
     errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
    if (errcode == 1405)
     exeResult = 1;
    else checkError();
   }
   else checkError();
}

Eof = (Fetched && !fCanFetch);
return (exeResult && fCanFetch);
}

【test.h】
#ifndef _TEST_H_
#define _TEST_H_
#include "OCI.h"
#endif

【test.cpp】

#include "test.h"

using namespace std;

OCIDatabase   OCIDB;

int main(int argc,char* argv[])
{
OCIQuery* q = new OCIQuery();
char SqlStr[256];
try                               
    {                     
    //断开已有的连接           
    OCIDB.disConnect();
    //设置登陆信息,Oracle数据库服务器IP地址为:192.168.0.1,端口为1521(通常都是1521)
    //serverdb为远程Oracle服务器服务名 usr为用户名 pwd为密码
        OCIDB.setLogin("//192.168.0.1:1521/serverdb", "usr", "pwd");
        //连接数据库
        if (OCIDB.connect() == 1)
        {
       fprintf(stdout,"connect db success/n");fflush(stdout);
    }
    else
    {
       fprintf(stdout,"connect db failure/n");fflush(stdout);
    }
    //为Query设置其连接的数据库
   q->setDB(&OCIDB);

/*演示select功能***********************************/
   //初始化一个Query
   q->close();
   //设置sql语句
   memset(SqlStr,0,sizeof(SqlStr));
   strcpy(SqlStr,"select * from table1");
        q->setSql(SqlStr);
        //执行select型sql语句-open
        q->open();
        //遍历结果集
        while(q->next())
   {
    //假设存在char型字段field1
    fprintf(stdout,"%c/n",q->fieldByName("field1")->asChar());
    //假设存在varchar2(或varchar)型字段field2
    fprintf(stdout,"%s/n",q->fieldByName("field2")->asString());
    //假设存在number型字段field3
    fprintf(stdout,"%d/n",q->fieldByName("field3")->asInteger());
    //假设存在float或double型字段field4
    fprintf(stdout,"%f/n",q->fieldByName("field4")->asFloat());
    //至于日期型字段,完全可以当作字符串来处理
    //具体方法就不用我说了,相信稍微熟悉Oracle sql语句的人都知道
      }
/*演示update功能***********************************/
   q->close();
   memset(SqlStr,0,sizeof(SqlStr));
   strcpy(SqlStr,"update table1 set field1 = 'T'");
   q->setSql(SqlStr);
   q->exec();//提交事务
   //注意:update和insert型sql语句执行完毕后需要提交/回滚
   q->commit();
/*演示delete功能***********************************/
   q->close();
   memset(SqlStr,0,sizeof(SqlStr));
   strcpy(SqlStr,"delete from table1");
   q->setSql(SqlStr);
   q->exec();
   q->rollBack();//回滚
  
   //收尾工作,释放资源
   q->close();
   delete q;
        OCIDB.disConnect();
}
   catch(OCIException &oe)           
    {                 
    fprintf(stdout,"%d-%s/n",oe.getErrNo(),oe.getErrInfo());
    OCIDB.disConnect();
    delete q;
    }
}

原创粉丝点击