免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4131 | 回复: 7
打印 上一主题 下一主题

Linux(Unix)下Oracle数据库访问接口程序OCI (Oracle Call Interface) 请求加精 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-20 00:03 |只看该作者 |倒序浏览
郑重声明:
本OCI(Oracle Call Interface)程序以C++编写,完全的面向对象.
具有快速,高效,可移植性好的特点,并经过严格的,长达3年以
上长时间的反复测试和使用,相信可满足大部分朋友的工作需要!
尤其适合应用在Linux/Unix服务器端编程使用.

并支持Oracle8,9,10...等各个版本,因为OCI是最底层的函数,自Oracle8版本以来变化较少!
可支持对char,varchar,varchar2,int,float,date等类型数据进行
select,update,insert操作,并支持事务的提交commit和回滚rollback.
共oci.h oci.cpp test.h test.cpp makefile 5个文件
可直接在Linux/Unix服务器上编译运行,当然前提条件是你的机器上装了
Oracle服务器端或客户端,(也可使用Oracle的Instant Client)并请你修改:
1.makefile中的 ORAINCLUDE 项以指定你机器上的Oracle头文件位置
2.makefile中的 ORALIBS    项以指定你机器上的Oracle库文件位置
作者:欧昕 中国-四川-成都
由于帖子长度过长,我把test.h和test.cpp两个文件的代码没有发上来,需要的
朋友可加我QQ,我把源文件全部发给你!我的联系QQ:30991118

有用的东西应该拿出来大家分享,欢迎OCI高手来指点!
[OCI.h]
//文件名之所以大写是为了避免和系统的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:MMD 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;
}

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->wd, strlen(db->wd),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->arentQuery = this;
                pCurrField->DataIndicator = new sb2[1];

                switch         (InnerDataType)
                {
                case SQLT_NUM:
                {
                        if (! InnerDataSize)
                                pCurrField->Size = 255;
                        else
                                pCurrField->Size = InnerDataSize;
                        pCurrField->recision = 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:pen()
{
        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;
        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;
        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);
}

[makefile]
CC                         = g++
CFLAGS                = -Wall
ORAINCLUDE         = -I /home/oracle8i/include
ORALIBS                 = -L /home/oracle8i/lib -lclntsh

all:test
test: OCI.o test.o
        $(CC) -o test *.o $(ORALIBS)

OCI.o: OCI.cpp OCI.h
        $(CC) $(CFLAGS) -c OCI.cpp $(ORAINCLUDE)
test.o: test.cpp test.h
        $(CC) $(CFLAGS) -c test.cpp $(ORAINCLUDE)

clean::
         rm -f *.o

[ 本帖最后由 oceania 于 2006-10-20 00:07 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-10-20 00:41 |只看该作者
好人, 赞一个

论坛徽章:
0
3 [报告]
发表于 2006-10-20 01:25 |只看该作者
来顶一下!

论坛徽章:
0
4 [报告]
发表于 2006-10-20 02:36 |只看该作者
oracle,蛤蟆跳水。。。
//比较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;
}

告诉你一个标准函数, strcasecmp

论坛徽章:
0
5 [报告]
发表于 2006-10-22 03:06 |只看该作者
谢谢你告诉我有这样一个函数,呵呵。但并不能因为我不知道有这样一个函数我就是蛤么,而你就是天鹅,你写一个OCI给我看看啊

论坛徽章:
0
6 [报告]
发表于 2006-11-14 13:39 |只看该作者
我要,给我一个!QQ95197055

论坛徽章:
0
7 [报告]
发表于 2006-11-14 14:37 |只看该作者
怎么才能联系到你亚

论坛徽章:
0
8 [报告]
发表于 2006-11-14 14:55 |只看该作者
原帖由 oceania 于 2006-10-22 03:06 发表
谢谢你告诉我有这样一个函数,呵呵。但并不能因为我不知道有这样一个函数我就是蛤么,而你就是天鹅,你写一个OCI给我看看啊


我说蛤蟆跳水意思是我不懂,不是说你是蛤蟆,哈哈
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP