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);
}

 

 

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值