OCI文档、C++实现例子

一、OCI是什么 


OCI
是一组底层的 API( 应用程序接口 ) ,主要和 Oracle 数据库进行交互。你可以调用一些 操作如  logon , execute, parse, fecth  等等。 OCI 支持大数据语言,通常使用 C/C++ 。与 Oracle Pro*C 等不同, OCI 不需要预编译。

 

OCIPro*C的一些优势:
  
  OCI
的性能十分出色
  
代码大量缩减
  
对内置函数直接访问
  
LONG类型的分段操作(可以处理LONG相关的任何错误)
  Pro*C
不能为绑定变量动态分配内存
  
不能控制Pro*C自动生成的代码

 

OCI开发流程:

  
连接多个数据库:使用OCILogon (olog, olon or orlon)
  
打开游标:oexec, oexn, ofen 或者 oftech
  
执行相应SQL语句
  
关于游标:oclose
  
断开连接:ologoff

 

二、各个函数介绍:

 

1.创建OCI环境 
sword OCIEnvCreate(   
OCIEnv **envhpp,  //OCI环境句柄指针 
ub4 mode,              //初始化模式:OCI_DEFAULT/OCI_THREADED 等 
CONST dvoid *ctxp, 
CONST dvoid *(*malicfp)(dvoid *ctxp,size_t size), 
CONST dvoid *(ralocfp)(dvoid *ctxp,dvoid *memptr,size_t newsize), 
CONST void *(*mfreefp)(dvoid *ctxp,dvoid *memptr), 
Size_t xstramemsz, 
Dvoid **usrmempp 
)

 

2.申请/释放句柄 
sword OCIHandleAlloc( 
CONST dvoid *parenth,  //新申请句柄的父句柄,一般为OCI环境句柄 
Dvoid **hndlpp,             //申请的新句柄  
Ub4 type, type,              //句柄类型 
Size_t xtramem_sz,       //申请的内存数 
Dvoid **usrmempp       //申请到的内存块指针 
)

 

3.读取/设置句柄属性 
sword OCIAttrSet( 
dvoid *trgthndlp,      //需设置的句柄名 
ub4  trghndltyp,       //句柄类型 
dvoid *attributep,    //设置的属性名 
ub4 size,                  //属性值长度 
ub4 attrtype,           //属性类型 
OCIError *errhp       //错误句柄 
)

 

4.连接/断开服务器 
   多用户方式连接: 
sword  OCIServerAttach( 
OCIServer     *srvhp,//未初始化的服务器句柄 
OCIError      *errhp, 
CONST text    *dblink,//服务器SID 
sb4           dblink_len, 
ub4           mode //=OCI_DEFAULT,系统环境将设为阻塞方式 
); 

sword OCIServerDetach ( 
OCIServer   *srvhp, 
OCIError    *errhp, 
ub4         mode //OCI_DEFAULT 
);  
单用户方式连接: 
sword OCILogon ( 
OCIEnv          *envhp, 
OCIError        *errhp, 
OCISvcCtx       **svchp, 
CONST text      *username, 
ub4             uname_len, 
CONST text      *password, 
ub4             passwd_len, 
CONST text      *dbname, 
ub4             dbname_len  
); 

sword OCILogoff (  
OCISvcCtx      *svchp 
OCIError       *errhp  
);

 

5.开始/结束一个会话 
先认证用户再建立一个会话连接 
sword OCISessionBegin (  
OCISvcCtx     *svchp,    //服务环境句柄 
OCIError      *errhp, 
OCISession    *usrhp,   //用户会话句柄 
ub4           credt,           //认证类型 
ub4           mode           //操作模式 
);

 

6.读取错误信息 
sword OCIErrorGet ( 
dvoid      *hndlp,             //错误句柄 
ub4        recordno,          /从那里读取错误记录,从1开始 
text       *sqlstate,         //已取消,=NULL 
sb4        *errcodep,       //错误号 
text       *bufp,              //错误内容 
ub4        bufsiz,             //bufp长度 
ub4        type                //传递的错误句柄类型 
=OCI_HTYPE_ERROR:错误句柄 
=OCI_HTYPE_ENV:环境句柄 
);

 

7.准备SQL语句 
sword OCIStmtPrepare (  
OCIStmt       *stmtp,  //语句句柄   
OCIError      *errhp, 
CONST text    *stmt,  //SQL语句 
ub4           stmt_len,   //语句长度 
ub4           language,  //语句的语法格式=OCI_NTV_SYNTAX 
ub4           mode         //=OCI_DEFAULT 
);

 

8. 绑定输入参数

sword OCIBindByName (  
OCIStmt       *stmtp, //语句句柄 
OCIBind       **bindpp,//结合句柄,=NULL 
OCIError      *errhp, 
CONST text    *placeholder,//占位符名称 
sb4           placeh_len, //占位符长度 
dvoid         *valuep, //绑定的变量名 
sb4           value_sz, //绑定的变量名长度 
ub2           dty,  //绑定的类型 
dvoid         *indp, //指示符变量指针(sb2类型),单条绑定时为NULL, 
ub2           *alenp, //说明执行前后被结合的数组变量中各元素数据实际的长度,单条绑定时为NULL 
ub2           *rcodep,//列级返回码数据指针,单条绑定时为NULL 
ub4           maxarr_len, //最多的记录数,如果是单条绑定,则为0 
ub4           *curelep, //实际的记录数,单条绑定则为NULL 
ub4           mode //=OCI_DEFAULT 
);  

sword OCIBindByPos ( OCIStmt      *stmtp,  
OCIBind      **bindpp, 
OCIError     *errhp, 
ub4          position,// 绑定的位置 
dvoid        *valuep, 
sb4          value_sz, 
ub2          dty, 
dvoid        *indp, 
ub2          *alenp, 
ub2          *rcodep, 
ub4          maxarr_len, 
ub4          *curelep,  
ub4          mode 

); 

9.执行SQL语句 
sword OCIStmtExecute (  
OCISvcCtx           *svchp,  //服务环境句柄 
OCIStmt             *stmtp,  //语句句柄 
OCIError            *errhp, 
ub4                 iters, // ** 
ub4                 rowoff, //** 
CONST OCISnapshot   *snap_in, 
OCISnapshot         *snap_out, 
ub4                 mode //** 
);

 

10.定义输出变量

sword OCIDefineByPos (  
OCIStmt     *stmtp, //语句句柄  
OCIDefine   **defnpp,//定义句柄—用于数组变量 
OCIError    *errhp, 
ub4         position,//位置序号(从1 开始) 
dvoid       *valuep, //输出的变量名 
sb4         value_sz, //变量长度 
ub2         dty,  //数据类型 
dvoid       *indp, //指示器变量/指示器变量数组,如果此字段可能存在空值,则要指示器变量,否则单条处理时为NULL 
ub2         *rlenp, //提取的数据长度 
ub2         *rcodep, //列级返回码数组指针 
ub4         mode //OCI_DEFAULT 
);

11.提取结果 
sword OCIStmtFetch ( 
OCIStmt     *stmtp,//语句句柄 
OCIError    *errhp,  
ub4         nrows, //从当前位置处开始一次提取的记录数,对于数据变量,可以>;1,否则不能>;1 
ub2         orientation,//提取的方向:OCI_FETCH_NEXT 
ub4         mode //OCI_DEFAULT 
) ;

 

C++实现例子:

DataBase.h文件:
#include <string>
#include <iostream>
//#include <stdlib.h>
#include <ctype.h>
#include <vector>
#ifndef _DATABASE_H_
#define _DATABASE_H_
#include <oratypes.h>
#include <ocidfn.h>
#include <ociapr.h>
#include <ocikpr.h>
#include <oci.h>
#define ORACLE
using namespace std;
//using namespace oracle::occi;

#define DB_SUCCESS    0   /*!< 成功标志*/
#define DB_FAILURE   -1   /*!< 失败标志*/
#define DB_NO_DATA_FOUND -100   /*!< 没有数据*/
#define DB_MAX_FIELD_LEN  257   /*!< 每个字段的最大长度*/
#define DB_MAX_COL_LEN     70   /*!< 每个表的最多列数*/
/*! @brief ORACLE连接结构*/
typedef struct _db_session
{
 OCIEnv  *envhp;
 OCIServer *srvhp;
 OCIError *errhp;
 OCISvcCtx *svchp;
 OCIStmt  *stmthp;
 OCIStmt  *selectp;
 OCISession *authp;
}DB_SESSION;
/*! @brief 字段记录*/
typedef  struct _db_record
{
   char field[DB_MAX_FIELD_LEN];  /*!< 字段*/
}DB_RECORD;
//oci查询返回的记录集
typedef struct TypeRecord {
 int rownum;  //记录集的行数
 int colnum;  //记录集的列数
 vector<char **> vRecord;
 char *rec(int i,int j){if(i < rownum && j < colnum) return vRecord[i][j]; return NULL;};
 int size(){return rownum >= 0 ? rownum : 0;};
} tRecordSet;
//绑定参数结构体定义
typedef struct TypeParam{
 int paramId;
 char vParam[50][50];
 int size;
}tParam;

/*! @brief 行标识*/
typedef OCIRowid  DB_ROWID;
#define OCI_TYPE_CHAR         0     /*!< char型数据类型定义 */
#define OCI_TYPE_INT          1     /*!< int型数据类型定义 */
#define OCI_TYPE_DATE         2     /*!< time_t型数据类型定义 */
#define OCI_TYPE_FLOAT        3     /*!< fload型数据类型定义 */
#define OCI_TYPE_DOUBLE       4     /*!< double型数据类型定义 */
#define OCI_TYPE_LONG         5     /*!< long型数据类型定义 */
class DataBase
{
public:
 DataBase(const char *user, const char *password, const char *server)
 {
  strcpy( DB_user, user );
  strcpy( DB_password, password);
  strcpy( DB_server, server );
  memset( errStr, 0, sizeof(errStr) );;
//  memset( tmpRec, 0, (sizeof(tmpRec)));
  
  DBSession = new DB_SESSION();
  memset( DBSession, 0, sizeof(DB_SESSION) );
 };
 
 short _DB_CheckErr(sword status )
 {
  char errBuf[512];
  sb4 errcode = 0;
  int i;
  
  switch (status)
  {
   case OCI_SUCCESS:  /*0*/
    return DB_SUCCESS;
  
   case OCI_SUCCESS_WITH_INFO:  /*1*/
    strcpy(errStr, "OCI_SUCCESS_WITH_INFO");
    break;
   case OCI_NEED_DATA:   /*99*/
    strcpy(errStr, "OCI_NEED_DATA");
    break;
   case OCI_NO_DATA:   /*100*/
    strcpy(errStr, "OCI_NO_DATA");
    return DB_NO_DATA_FOUND;
  
   case OCI_ERROR:   /*-1*/
    (void) OCIErrorGet((dvoid *)DBSession->errhp, (ub4) 1, (text *) NULL, &errcode,
        (text *)errBuf, (ub4) sizeof(errBuf), OCI_HTYPE_ERROR);
    if(1405 == errcode)
     return DB_SUCCESS;   /*列为空值时不是错误*/
  
    errBuf[100]='/0';
    for(i=0;i<(int)strlen(errBuf);i++)
    {
     if(errBuf[i]=='/n')
     {
      errBuf[i]='/0';
      break;
     }
    }
    strcpy(errStr, errBuf);
    break;
   case OCI_INVALID_HANDLE:   /*-2*/
    strcpy(errStr, "OCI_INVALID_HANDLE");
    break;
   case OCI_STILL_EXECUTING:   /*-3123*/
    strcpy(errStr, "OCI_STILL_EXECUTING");
    break;
   case OCI_CONTINUE:   /*-24200*/
    strcpy(errStr, "OCI_CONTINUE");
    break;
   default:
    strcpy(errStr, "DEFAULT");
  }
  return DB_FAILURE;
 };
 ~DataBase()
 {
  if(NULL==DBSession)
  return;
  _DB_EndTrans(1);
  
  // Release SQL statement handler
  if (DBSession->stmthp != NULL)
  {
   OCIHandleFree((dvoid *)(DBSession->stmthp), OCI_HTYPE_STMT);
   DBSession->stmthp = NULL;
  }
  if (DBSession->selectp != NULL)
  {
   OCIHandleFree((dvoid *)(DBSession->selectp), OCI_HTYPE_STMT);
   DBSession->selectp = NULL;
  }
  // Delete the user session 
  if (DBSession->authp != NULL)
  {
   OCISessionEnd(DBSession->svchp, DBSession->errhp, DBSession->authp, (ub4)OCI_DEFAULT);
   DBSession->authp = NULL;
  }
  // Delete access to the data source 
  if (DBSession->errhp)
  {
   OCIServerDetach(DBSession->srvhp, DBSession->errhp, OCI_DEFAULT);
  }
  // Explicitly deallocate all handles 
  if (DBSession->srvhp != NULL)
  {
   OCIHandleFree((dvoid *)(DBSession->srvhp), OCI_HTYPE_SERVER);
   DBSession->srvhp = NULL;
  }
  if (DBSession->svchp != NULL)
  {
   OCIHandleFree((dvoid *)(DBSession->svchp), OCI_HTYPE_SVCCTX);
   DBSession->svchp = NULL;
  }
  if (DBSession->errhp != NULL)
  {
   OCIHandleFree((dvoid *)(DBSession->errhp), OCI_HTYPE_ERROR);
   DBSession->errhp = NULL;
  }
  DBSession = NULL;
  
  return;
 };
 
 //初始化DCI连接
 int _DB_Connect();
 //断开数据库
 void _DB_Disconnect();
  
 int _DB_PrepareSQL(string &sql);
 
 int _DB_ExecuteSQL();
 
 int _DB_ExecuteSQL_P();
 
 int _DB_BindParam(int paramId, int dataType, void *param);
 
 int _DB_RecordSetCol();
 
 void _DB_RecordSet();
 
 void _DB_CleanRecordSet();
 
 int _DB_FetchData();
 
 void _DB_EndTrans(int flag);
 
 tRecordSet RecordSet;
private:
 char DB_user[8];
 char DB_password[8];
 char DB_server[9];
 DB_SESSION *DBSession;
 char errStr[50];
 char strSql[1024];
 
 char** tmpRec;
 tParam tmpParam;
 
};

#endif
DataBase.cpp文件:
#include "DataBase.h"
int DataBase::_DB_Connect()
{
 if( OCIInitialize((ub4) OCI_OBJECT, (dvoid *)0,(dvoid * (*)(dvoid *, size_t)) 0,(dvoid * (*)(dvoid *, dvoid *, size_t))0,
     (void (*)(dvoid *, dvoid *)) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIInitialize");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;  
  return OCI_ERROR;
 }
     
 if( OCIEnvInit( (OCIEnv **) &(DBSession->envhp), OCI_DEFAULT, (size_t) 0, (dvoid **) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIEnvInit");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIHandleAlloc( (dvoid *) (DBSession->envhp), (dvoid **) &(DBSession->errhp), OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIHandleAlloc On Error Handle");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIHandleAlloc( (dvoid *) (DBSession->envhp), (dvoid **) &(DBSession->srvhp), OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIHandleAlloc On Srv Handle");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIHandleAlloc( (dvoid *) (DBSession->envhp), (dvoid **) &(DBSession->svchp), OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIHandleAlloc On Service Context Handle");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIServerAttach( DBSession->srvhp, DBSession->errhp, (text *)DB_server, strlen(DB_server), 0 ) )
 {
  sprintf(errStr, "FAILED:OCIServerAttach (Can't connect to %s)", DB_server );
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIAttrSet( (dvoid *) (DBSession->svchp), OCI_HTYPE_SVCCTX, (dvoid *)(DBSession->srvhp), (ub4) 0, OCI_ATTR_SERVER, (OCIError *) (DBSession->errhp) ) )
 {
  strcpy(errStr, "FAILED:OCIAttrSet" );
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIHandleAlloc((dvoid *) (DBSession->envhp), (dvoid **)&(DBSession->authp), (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0 ) )
 {
  strcpy(errStr, "FAILED:OCIHandleAlloc On Authentication Handle" );
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 if( OCIAttrSet((dvoid *) (DBSession->authp), (ub4) OCI_HTYPE_SESSION, (dvoid *) DB_user, (ub4) strlen(DB_user),
    (ub4) OCI_ATTR_USERNAME, DBSession->errhp ) )
 {
  strcpy(errStr, "FAILED:OCIAttrSet on USERID" );
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 if( OCIAttrSet((dvoid *) (DBSession->authp), (ub4) OCI_HTYPE_SESSION, (dvoid *)DB_password, (ub4) strlen(DB_password),
    (ub4) OCI_ATTR_PASSWORD, DBSession->errhp ) )
 {
  strcpy(errStr, "FAILED:OCIAttrSet on PASSWD");
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 //认证用户并建立会话
 if( _DB_CheckErr(OCISessionBegin ( DBSession->svchp,
  DBSession->errhp, DBSession->authp, OCI_CRED_RDBMS, (ub4) OCI_DEFAULT)) < 0 )
 {
  return OCI_ERROR;
 }
    
 if( OCIAttrSet((dvoid *) (DBSession->svchp), (ub4) OCI_HTYPE_SVCCTX, (dvoid *) (DBSession->authp), (ub4) 0,
    (ub4) OCI_ATTR_SESSION, (DBSession->errhp) ) )
 {
  strcpy(errStr, "FAILED:OCIAttrSet on session" );
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return OCI_ERROR;
 }
 
 //申请语句句柄
 if( _DB_CheckErr(OCIHandleAlloc( (dvoid *) (DBSession->envhp),
  (dvoid **) &(DBSession->stmthp),    OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0))<0)
 {
  return OCI_ERROR;
 }
 
 if( _DB_CheckErr(OCIHandleAlloc( (dvoid *) (DBSession->envhp),
  (dvoid **) &(DBSession->selectp),    OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)) < 0 )
 {
  return OCI_ERROR;
 }
 return OCI_SUCCESS;
}
int DataBase::_DB_PrepareSQL(string &sql)
{
 tmpParam.size = 0;
 memset(strSql, 0 ,sizeof(strSql) ); 
 sprintf(strSql, "%s", sql.c_str() );
 if( _DB_CheckErr(OCIStmtPrepare( DBSession->selectp,
  DBSession->errhp, (text *)strSql, (ub4)strlen( (char *)strSql ),
  (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT)) < 0 )
 {
  cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl; 
  return DB_FAILURE;
 }
 
 return OCI_SUCCESS;
}
int DataBase::_DB_ExecuteSQL()
{
 //绑定变量
 OCIBind *bindHandle[50];    // 最多支持50个参数
 char fieldName[10];
 for(int i = 0; i < tmpParam.size; i++)
 {
  sprintf(fieldName, ":v%d", i+1);
  if( _DB_CheckErr(OCIBindByName(DBSession->selectp,
   &bindHandle[i], DBSession->errhp, (text *) fieldName,
   -1, (dvoid *)(tmpParam.vParam[i]),
   (sword) DB_MAX_FIELD_LEN, SQLT_STR, (dvoid *) 0,
   (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)) < 0 )
  {
   cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
   return DB_FAILURE;
  }
 }
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] strSql = "<<strSql<<endl;
 //执行SQL
 if( _DB_CheckErr(OCIStmtExecute( DBSession->svchp, DBSession->selectp,
   DBSession->errhp, (ub4) 0, (ub4) 0, (CONST OCISnapshot *)NULL,
   (OCISnapshot *)NULL, OCI_DEFAULT) ) < 0 )
 {
  cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
  return DB_FAILURE;
 }
 //取字段个数
 int colNum = _DB_RecordSetCol();
 
 //结构数据绑定
 OCIDefine *defnp[100];
// memset(tmpRec, 0, (sizeof(DB_RECORD) * colNum) + 1);
 tmpRec = new char*[50];
 for(i = 0; i < colNum; i++)
 {
  defnp[i] = (OCIDefine *) 0;
  tmpRec[i] = new char[DB_MAX_FIELD_LEN];
//  memset(tmpRec[i], 0, sizeof(char)*DB_MAX_FIELD_LEN);
  if( _DB_CheckErr(OCIDefineByPos( DBSession->selectp,
   &defnp[i], DBSession->errhp,  i+1, (dvoid *) tmpRec[i],
   colNum*sizeof(DB_RECORD), SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT) ) < 0 )
  {
   cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
   return DB_FAILURE;
  }
 }
// delete[] tmpRec;
 
 return DB_SUCCESS;
}
int DataBase::_DB_RecordSetCol()
{
 int colNum;
 
 if( _DB_CheckErr(OCIAttrGet(DBSession->selectp, OCI_HTYPE_STMT, &colNum, 0, OCI_ATTR_PARAM_COUNT, DBSession->errhp) ) <  0 )
 {
  cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
  return DB_FAILURE;
 }
 
 return colNum;
}
int DataBase::_DB_FetchData()
{
 return( _DB_CheckErr( OCIStmtFetch( DBSession->selectp, DBSession->errhp, (ub4)1, (ub4)OCI_FETCH_NEXT, (ub4) OCI_DEFAULT ) ) );
}
void DataBase::_DB_RecordSet()
{
 _DB_CleanRecordSet();
 int col = _DB_RecordSetCol();
 RecordSet.colnum = col;
 RecordSet.rownum = 0; 
 
 while(0 == _DB_FetchData() )
 {
  char **p = new char*[col];
  for(int k = 0; k < col; k++)
  {
   p[k] = new char[strlen(tmpRec[k]) + 1];
   memcpy(p[k], tmpRec[k], strlen(tmpRec[k]) + 1); 
  }
  RecordSet.vRecord.push_back(p);
  RecordSet.rownum++;
 }
 
}
int DataBase::_DB_BindParam(int paramId, int dataType, void *param)
{
 memset(tmpParam.vParam[paramId], 0, sizeof(tParam));
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] tmpParam.size = "<<tmpParam.size<<endl; 
 switch(dataType)
 {
  case OCI_TYPE_CHAR:
   tmpParam.paramId = paramId;
   sprintf(tmpParam.vParam[paramId], "%s", (char *)param);
   tmpParam.size = paramId + 1;
   break;
  case OCI_TYPE_LONG:
   tmpParam.paramId = paramId;
   sprintf(tmpParam.vParam[paramId], "%ld", *(long *)param);
   tmpParam.size = paramId + 1;
   break;
 }
  
 return DB_SUCCESS;
}
void DataBase::_DB_EndTrans(int flag)
{
 if(0 == flag)        
  OCITransCommit(DBSession->svchp, DBSession->errhp, (ub4) 0);
 else
  OCITransRollback(DBSession->svchp, DBSession->errhp, (ub4) 0);
  
 return;
}

void DataBase::_DB_CleanRecordSet()
{
 if( RecordSet.rownum <= 0 ){
  RecordSet.colnum = 0;
  return;
 }
 for(int k = 0; k < RecordSet.rownum; k++ )
 {
  for( int j = 0; j< RecordSet.colnum; j++ )
  {
   if( RecordSet.vRecord[k][j])
   {
    delete [] RecordSet.vRecord[k][j];
    RecordSet.vRecord[k][j]=NULL;
   }
  }
  if(RecordSet.vRecord[k])
  {
   delete [] RecordSet.vRecord[k];
   RecordSet.vRecord[k] = NULL;
  }
 }
 
 RecordSet.rownum = 0;
 RecordSet.colnum = 0;
 RecordSet.vRecord.clear();
}
int DataBase::_DB_ExecuteSQL_P()
{
  //绑定变量
 OCIBind *bindHandle[50];    // 最多支持50个参数
 char fieldName[10];
 
 for(int i = 0; i < tmpParam.size; i++)
 {
  sprintf(fieldName, ":v%d", i+1);
  if( _DB_CheckErr(OCIBindByName(DBSession->selectp,
   &bindHandle[i], DBSession->errhp, (text *) fieldName,
   -1, (dvoid *)(tmpParam.vParam[i]),
   (sword) DB_MAX_FIELD_LEN, SQLT_STR, (dvoid *) 0,
   (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)) < 0 )
  {
   cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
   return DB_FAILURE;
  }
 }
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] strSql = "<<strSql<<endl;
 //执行SQL
 if( _DB_CheckErr(OCIStmtExecute( DBSession->svchp, DBSession->selectp,
   DBSession->errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *)NULL,
   (OCISnapshot *)NULL, OCI_DEFAULT) ) < 0 )
 {
  cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
  return DB_FAILURE;
 }
 //取字段个数
 int colNum = _DB_RecordSetCol();
 
 //结构数据绑定
 OCIDefine *defnp[100];
 tmpRec = new char*[50];
 for(i = 0; i < colNum; i++)
 {
  defnp[i] = (OCIDefine *) 0;
  memset(tmpRec[i], 0, sizeof(char)*DB_MAX_FIELD_LEN);
  tmpRec[i] = new char[DB_MAX_FIELD_LEN];
  if( _DB_CheckErr(OCIDefineByPos( DBSession->selectp,
   &defnp[i], DBSession->errhp,  i+1, (dvoid *) (tmpRec + i),
   colNum*sizeof(DB_RECORD), SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT) ) < 0 )
  {
   cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] errStr = "<<errStr<<endl;
   return DB_FAILURE;
  }
 }
 
 return DB_SUCCESS;
}
 
Main函数文件:
#include "DataBase.h"
/*  测试表 ************************
create table TEST_TAB
(
  ID   NUMBER(10),
  NAME CHAR(10),
  AGE  NUMBER(10)
)
*/
 
main()
{
 int flag;
 int i;
 
 DataBase db( "billopr", "billopr", "accpstdb" );
 flag = db._DB_Connect();
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_Connect() = "<<flag<<endl;
 }
 
 string sql;
 sql = string( "" ) + "select * from test_tab where id = 11";
 flag = db._DB_PrepareSQL(sql);
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_PrepareSQL() = "<<flag<<endl;
 }
 
 flag = db._DB_ExecuteSQL();
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_ExecuteSQL() = "<<flag<<endl;
 }
 db._DB_RecordSet();
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.colnum = "<<db.RecordSet.colnum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.rownum = "<<db.RecordSet.rownum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.size() = "<<db.RecordSet.size()<<endl;
 
 for(i = 0; i < db.RecordSet.size(); i++)
 { 
  for(int j = 0; j < db.RecordSet.colnum; j++ )
  {
   cout<<db.RecordSet.rec(i, j)<<"/t";
  }
  cout<<endl;
 }
 
 sql = string( "" ) + "select * from test_tab where id = :v1 and age > :v2";
 char *num1 = "13";
 char *num2 = "0";
 flag = db._DB_PrepareSQL(sql);
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_PrepareSQL() = "<<flag<<endl;
 }
 
 flag = db._DB_BindParam(0, OCI_TYPE_CHAR, num1);
  if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_BindParam() = "<<flag<<endl;
 }
 flag = db._DB_BindParam(1, OCI_TYPE_CHAR, num2);
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_BindParam() = "<<flag<<endl;
 }
 
 flag = db._DB_ExecuteSQL();
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_ExecuteSQL() = "<<flag<<endl;
 }
 db._DB_RecordSet();
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.colnum = "<<db.RecordSet.colnum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.rownum = "<<db.RecordSet.rownum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.size() = "<<db.RecordSet.size()<<endl;
// tmpRec = &(db._DB_FetchData());
 
 for(i = 0; i < db.RecordSet.size(); i++)
 { 
  for(int j = 0; j < db.RecordSet.colnum; j++ )
  {
   cout<<db.RecordSet.rec(i, j)<<"/t";
  }
  cout<<endl;
 }
 
 
 sql = string( "" ) + "insert into test_tab values(:v1, :v2, :v3)";
// char *num1 = "25";
// char *num2 = "wwwwwwww";
 char *num3 = "30";
 flag = db._DB_PrepareSQL(sql);
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_PrepareSQL() = "<<flag<<endl;
 }
 
 flag = db._DB_BindParam(0, OCI_TYPE_CHAR, num1);
 flag = db._DB_BindParam(1, OCI_TYPE_CHAR, num2);
 flag = db._DB_BindParam(2, OCI_TYPE_CHAR, num3);
 
 if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_BindParam() = "<<flag<<endl;
 }
 
 flag = db._DB_ExecuteSQL_P();
/* if( flag != OCI_SUCCESS )
 {
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] db._DB_ExecuteSQL() = "<<flag<<endl;
 }
 db._DB_RecordSet();
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.colnum = "<<db.RecordSet.colnum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.rownum = "<<db.RecordSet.rownum<<endl;
cout<<"[ "<<__FILE__<<" ] [ "<<__LINE__<<" ] RecordSet.size() = "<<db.RecordSet.size()<<endl;
// tmpRec = &(db._DB_FetchData());
 
 for(i = 0; i < db.RecordSet.size(); i++)
 { 
  for(int j = 0; j < db.RecordSet.colnum; j++ )
  {
   cout<<db.RecordSet.rec(i, j)<<"/t";
  }
  cout<<endl;
 }*/
 db._DB_EndTrans(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值