Linux下使用C/C++访问数据库——Oracle之OCI篇


一、什么是OCI?
开发基于Oracle数据库的应用程序,我们可以选择多种工具,不仅可以用一般的数据库开发技术,诸如ADO(ActiveX Data Objects)、ODBC(Open DataBase Connectivity)等等,同时,也可以用Oracle公司提供的专门的开发工具,诸如Pro C_C++,OCI(Oracle Call Intedace)等等。比较这几种方式,前者因为是通用技术,开发起来比较容易,但是有一个致命的弱点就是诸如ADO之类的通用技术的速度太慢,如果我们要开发管理海量数据的数据库,比如影像数据库,那么,这种速度我们是不能忍受的。而OCI虽然开发起来难度大一些,但是它的速度极快,而且是一种底层接口,几乎可以操纵Oracle数据库的任何对象。
二、OCI简介
OCI(Oracle Call Intedace,即0racle调用层接口)是Oracle公司提供的由头文件和库函数等组成的一个访问Oracle数据库的应用程序编程接口(application programming interface  API),它允许开发人员在第三代编程语言(包括C, C++, COBOL 与 FORTRAN)中通过SQL(Structure Query Language)来操纵Oracle数据库,而且OCI在一定程度上支持第三代编程语言(诸如C, C++, COBOL 与 FORTRAN)的数据类型、语法等等。OCI的显著特点是全面支持Oracle的面向对象技术,同时OCI还具有如下的一些特点:
1)非常有利于应用程序的设计;
2)高度控制应用程序的执行;
3)允许开发人员应用已熟悉的第三代程序设计语言来应用OCI;
4)支持动态SQL;
5)几乎所有的Oracle的开发工具都支持OCI;
6)通过回调技术(callbacks)来实现动态绑定与定义;
7)通过OCI的描述函数可以获取Oracle数据库的各种参数;
8)增强了数组在DML(data manipulation language)语言中的应用;
OCI接口支持Windows NT和Windows 95/98/2000/XP操作系统,它所支持的C语言编译器包括Borland C++和MiroSoft VisualC++等。在使用0CI开发Oralce数据库应用程序之前,应首先安装这些操作系统和C语言编译工具。在选择安装OCI开发工具包后,Oracle安装程序将0CI文件拷贝到oracle主目录内的以下子目录中:
..BIN\:执行文件和帮助文件:
..\OCIINCLUDE头文件;
三、开发前的注意事项
首先,为了防止某些动态链接库出问题,建议在安装了Oracle客户端的机器上进行开发、运行。
其次,使用OCI开发的程序,需要使用Oracle客户端的tnsnames.ora这个配置文件,所以在开发前需要使用netca来配置好相关内容。
第三,Linux下的系统环境变量需要设置好。需要设置的环境变量包括ORACLE_HOME、ORACLE_SID、TNS_ADMIN,其中TNS_ADMIN指定到tnsnames.ora所在的文件夹。
四、程序开发:
还是直接用代码说话吧
/* 
* Common.h 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 

#ifndef COMMON_H_ 
#define COMMON_H_ 

#include <unistd.h> 
#include <oci.h> 
#include <ctype.h> 

#include <string> 
#include <iostream> 
#include <vector> 

#include <string.h> 

using namespace std; 

#endif /* COMMON_H_ */ 
 
/* 
* Exception.h 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 

#ifndef EXCEPTION_H_ 
#define EXCEPTION_H_ 

class Exception 

public: 
  Exception(int errno); 
  virtual char * GetErrMsg() = 0; 
  virtual char * GetErrFunc() = 0; 
  virtual int GetErrNo() = 0; 
protected: 
  int m_iErrNo; 
  char m_sErrBuff[512]; 
  char m_sErrFunc[128]; 
}; 

#endif /* EXCEPTION_H_ */ 
 
/* 
* Exception.cpp 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 
#include "Exception.h" 

Exception::Exception(int errno) 

  this ->m_iErrNo = errno; 
  this ->m_sErrBuff[0] = 0; 
  this ->m_sErrFunc[0] = 0; 

 
/* 
* OCIException.h 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 

#ifndef OCIEXCEPTION_H_ 
#define OCIEXCEPTION_H_ 

#include "Common.h" 
#include "Exception.h" 

class OCIException : public Exception 

public: 
  OCIException(sb4 errno); 
  OCIException(sb4 errno, char * errfunc); 
  OCIException(sb4 errno, dvoid * erroci); 
  OCIException(sb4 errno, dvoid * erroci, char * errfunc); 

  char * GetErrMsg(); 
  char * GetErrFunc(); 
  int GetErrNo(); 
private: 
  void CheckError(sb4 errno); 
  void CheckError(sb4 errno, dvoid * erroci); 
}; 

#endif /* OCIEXCEPTION_H_ */ 
 
/* 
* OCIException.cpp 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 
#include "OCIException.h" 

void OCIException::CheckError(sb4 errno) 

  text errBuff[512]; 
  switch ( errno ) 
  { 
  case OCI_SUCCESS: 
    break; 
  case OCI_SUCCESS_WITH_INFO: 
    sprintf( this ->m_sErrBuff, "OCI_SUCCESS_WITH_INFO" ); 
    break; 
  case OCI_NEED_DATA: 
    sprintf( this ->m_sErrBuff, "OCI_NEED_DATA" ); 
    break; 
  case OCI_NO_DATA: 
    sprintf( this ->m_sErrBuff, "OCI_NO_DATA" ); 
    break; 
  case OCI_ERROR: 
    sprintf( this ->m_sErrBuff, "OCI_ERROR" ); 
    break; 
  case OCI_INVALID_HANDLE: 
    sprintf( this ->m_sErrBuff, "OCI_INVALID_HANDLE" ); 
    break; 
  case OCI_STILL_EXECUTING: 
    sprintf( this ->m_sErrBuff, "OCI_STILL_EXCUTING" ); 
    break; 
  case OCI_CONTINUE: 
    sprintf( this ->m_sErrBuff, "OCI_CONTINUE" ); 
    break; 
  default: 
    break; 
  } 


void OCIException::CheckError(sb4 errno, dvoid * erroci) 

  text errBuff[512]; 
  switch ( errno ) 
  { 
  case OCI_SUCCESS: 
    break; 
  case OCI_SUCCESS_WITH_INFO: 
    sprintf( this ->m_sErrBuff, "OCI_SUCCESS_WITH_INFO" ); 
    break; 
  case OCI_NEED_DATA: 
    sprintf( this ->m_sErrBuff, "OCI_NEED_DATA" ); 
    break; 
  case OCI_NO_DATA: 
    sprintf( this ->m_sErrBuff, "OCI_NO_DATA" ); 
    break; 
  case OCI_ERROR: 
    OCIErrorGet( (dvoid*)erroci, (ub4)1, (text*)NULL, &this ->m_iErrNo, errBuff, (ub4)sizeof(errBuff), OCI_HTYPE_ERROR); 
    sprintf( this ->m_sErrBuff, "%.*s", strlen((char*) errBuff) - 1, errBuff); 
    break; 
  case OCI_INVALID_HANDLE: 
    sprintf( this ->m_sErrBuff, "OCI_INVALID_HANDLE" ); 
    break; 
  case OCI_STILL_EXECUTING: 
    sprintf( this ->m_sErrBuff, "OCI_STILL_EXCUTING" ); 
    break; 
  case OCI_CONTINUE: 
    sprintf( this ->m_sErrBuff, "OCI_CONTINUE" ); 
    break; 
  default: 
    break; 
  } 


OCIException::OCIException(sb4 errno) : Exception( (int)errno ) 

  this ->CheckError(errno); 


OCIException::OCIException(sb4 errno, char * errfunc) : Exception( (int)errno ) 

  strcpy( this ->m_sErrBuff, errfunc); 
  this ->CheckError(errno); 


OCIException::OCIException(sb4 errno, dvoid * erroci) : Exception( (int)errno ) 

  this ->CheckError(errno, erroci); 


OCIException::OCIException(sb4 errno, dvoid * erroci, char * errfunc) : Exception( (int)errno ) 

  strcpy( this ->m_sErrBuff, errfunc); 
  this ->CheckError(errno, erroci); 


char * OCIException::GetErrMsg() 

  return this ->m_sErrBuff; 


char * OCIException::GetErrFunc() 

  return this ->m_sErrFunc; 


int OCIException::GetErrNo() 

  return this ->m_iErrNo; 

 
/* 
* OCIError.h 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 

#ifndef OCIERROR_H_ 
#define OCIERROR_H_ 

#include "Common.h" 

class OCIError 

public: 
  static void PrintError(int errno); 
  static void PrintError(int errno, char * errfunc); 
private: 
  static void CheckError(); 
  static int m_iErrNo; 
  static char m_sErrBuff[512]; 
  static char m_sErrFunc[128]; 
}; 

#endif /* OCIERROR_H_ */ 
 
/* 
* OCIError.cpp 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 
#include "OCIError.h" 

int OCIError::m_iErrNo = 0; 
char OCIError::m_sErrBuff[512] = {0}; 
char OCIError::m_sErrFunc[128] = {0}; 

void OCIError::CheckError() 

  switch ( OCIError::m_iErrNo ) 
  { 
  case OCI_SUCCESS: 
    break; 
  case OCI_SUCCESS_WITH_INFO: 
    sprintf( OCIError::m_sErrBuff, "OCI_SUCCESS_WITH_INFO" ); 
    break; 
  case OCI_NEED_DATA: 
    sprintf( OCIError::m_sErrBuff, "OCI_NEED_DATA" ); 
    break; 
  case OCI_NO_DATA: 
    sprintf( OCIError::m_sErrBuff, "OCI_NO_DATA" ); 
    break; 
  case OCI_ERROR: 
    sprintf( OCIError::m_sErrBuff, "OCI_ERROR" ); 
    break; 
  case OCI_INVALID_HANDLE: 
    sprintf( OCIError::m_sErrBuff, "OCI_INVALID_HANDLE" ); 
    break; 
  case OCI_STILL_EXECUTING: 
    sprintf( OCIError::m_sErrBuff, "OCI_STILL_EXCUTING" ); 
    break; 
  case OCI_CONTINUE: 
    sprintf( OCIError::m_sErrBuff, "OCI_CONTINUE" ); 
    break; 
  default: 
    break; 
  } 


void OCIError::PrintError(int errno) 

  OCIError::m_iErrNo = errno; 
  OCIError::CheckError(); 
  std::cout << OCIError::m_sErrBuff << std::endl; 


void OCIError::PrintError(int errno, char * errfunc ) 

  OCIError::m_iErrNo = errno; 
  strcpy(OCIError::m_sErrFunc, errfunc); 
  OCIError::CheckError(); 
  std::cout << OCIError::m_sErrFunc << OCIError::m_sErrBuff << std::endl; 

 
/* 
* OCIDB.h 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 

#ifndef OCIDB_H_ 
#define OCIDB_H_ 

#include "Common.h" 
#include "../Common/CheckStringTools.h" 

#define MAX_VAR_LEN 10 
#define MAX_BUFFER_SIZE 32767 

typedef struct { 
  ub2    VarType; 
  char *  VarName; 
  int    VarLen; 
  union { 
    char * ValueChar; 
    float * ValueFloat; 
    int * ValueInt; 
    OCILobLocator *lobLocator; 
  }; 
} TBindVar; 

typedef struct{ 
  char VarName[MAX_VAR_LEN]; 
  unsigned char VarType; 
  unsigned char VarSize; 
  unsigned char VarPrecision; 
  unsigned char VarScale; 
  unsigned char VarIsNull; 
  union { 
    char * ValueChar; 
    float * ValueFloat; 
    int * ValueInt; 
    OCILobLocator *lobLocator; 
  }; 
} TSelectVar; 

#define MAX_BINDVAR_COUNT 10 
#define MAX_SELECTVAR_COUNT 10 

#define TYPE_INT 0 
#define TYPE_FLOAT 1 
#define TYPE_STRING 2 
#define TYPE_BLOB 3 

class OCIDB 

private: 
  dvoid * indp; 
  OCIEnv * m_pOCIEnv; 
  OCIError * m_pOCIError; 

  OCISvcCtx * m_pOCISvcCtx; 
  OCIServer * m_pOCIServer; 
  OCISession * m_pOCISession; 

  OCIStmt * m_pOCIStmt; 
  OCIBind * m_pOCIBind; 
  OCIDefine * m_pOCIDefine; 
  OCIParam * m_pOCIParam; 

  TBindVar m_BindVars[MAX_BINDVAR_COUNT]; 
  TSelectVar m_SelectVars[MAX_SELECTVAR_COUNT]; 

  int m_iBindVarsCount; 
  int m_iSelectVarsCount; 

  char m_sUser[10]; 
  char m_sPwd[10]; 
  char m_sDBName[10]; 

  int UserFetch(); 
  int UserGetInt(int index); 
  int UserGetInt(char * name); 
  char * UserGetString(int index); 
  char * UserGetString(char * name); 
  char * UserGetBlob(int index); 
  char * UserGetBlob(char * name); 
  float UserGetFloat(int index); 
  float UserGetFloat(char * name); 
  void inline StrUpper(char *str); 
  bool inline StrCmp(const char *ori, const char *des); 
  vector< vector<string> > resultList; 
protected: 
  char * getBlobValue(); 
public: 
  OCIDB(); 
  ~OCIDB(); 

  /* Single User, Single Connection */ 
  int Single_Conn(); 
  void Single_Disc(); 

  /* Multiple Sessions or Connections */ 
  int Multiple_Conn(); 
  void Multiple_Disc(); 

  /* Execute SQL with none query */ 
  int ExcuteSQL(char * sql); 

  /* Execute SQL with bind vars */ 
  void BindInitVars(); 
  void BindClearVars(); 
  void BindAddVar(char * name, char * value); 
  void BindAddVar(char * name, int * value); 
  int BindSQL(char * sql); 

  /* Prepare SQL*/ 
  int UserPrepare(char * sql); 
  int UserFree(); 
  int UserBind(char * name, char * value); 
  int UserBind(char * name, int value); 
  int UserExecute(); 
  int UserCommit(); 
  int UserRollback(); 

  int UserSelect(char * sql); 
  int UserSelectFree(); 

  vector< vector<string> > getResult(); 
}; 

#endif /* OCIDB_H_ */ 
 
/* 
* OCIDB.cpp 

*    Created .: Mar 1, 2009 
*            Author: Steven Wee 
*/ 
#include "OCIDB.h" 
#include "OCIException.h" 
#include "OCIError.h" 

OCIDB::OCIDB() 

  strcpy(this ->m_sUser, "webtest"); 
  strcpy(this ->m_sPwd, "ns0528AO"); 
  strcpy(this ->m_sDBName, "NSTEST"); 

  this ->BindInitVars(); 


OCIDB::~OCIDB() 




int OCIDB::Single_Conn() 

  try 
  { 
    sword errno; 
    /* 
     * OCIEnvCreate(&envhp, mode, (const dvoid *)0, 0, 0, 0, (size_t)0, (dvoid **)0 ); 
     */ 
    errno = OCIEnvCreate( &this ->m_pOCIEnv, OCI_OBJECT, (dvoid *)0, (dvoid *(*)(dvoid *, size_t))0, (dvoid *(*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0, (size_t)0, (dvoid **)0); 
    if(errno) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Single_Conn OCIEnvCreate"); 
    } 

    /* Create Error Handle */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIError, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); 
    if(errno) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Single_Conn OCIHandleAlloc"); 
    } 

    /* Login */ 
    errno = OCILogon(this ->m_pOCIEnv, this ->m_pOCIError, &this ->m_pOCISvcCtx, (const OraText*)this ->m_sUser, 
        strlen(this ->m_sUser), (const OraText*)this ->m_sPwd, strlen(this ->m_sPwd), (const OraText*)this ->m_sDBName, 
        strlen(this ->m_sDBName)); 
    if(errno) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::Single_Conn OCILogin2"); 
    } 

    return 0; 
  } 
  catch ( OCIException &ex) 
  { 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


void OCIDB::Single_Disc() 

  sword errno; 
  /* Log off */ 
  errno = OCILogoff(m_pOCISvcCtx, this ->m_pOCIError); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Single_Disc OCILogoff"); 
  } 

  /* Free errno */ 
  errno = OCIHandleFree((dvoid *)this ->m_pOCIError, (ub4)OCI_HTYPE_ERROR); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Single_Disc OCIHandleFree"); 
  } 

  /* Free Env Handle */ 
  errno = OCIHandleFree((dvoid *)this ->m_pOCIEnv, (ub4)OCI_HTYPE_ENV); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Single_Disc OCIHandleFree"); 
  } 


int OCIDB::Multiple_Conn() 

  try 
  { 
    sword errno; 

    errno = OCIInitialize( (ub4)OCI_DEFAULT, (dvoid *)0, (dvoid *(*)(dvoid *, size_t))0, (dvoid *(*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0 ); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIInitialize"); 
    } 
    errno = OCIEnvInit( (OCIEnv **)&this ->m_pOCIEnv, OCI_DEFAULT, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIEnvInit"); 
    } 

    /* Allocate Error Handle */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIError, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIHandleAlloc Error"); 
    } 

    /* Allocate Server Context Handle */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCISvcCtx, OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIHandleAlloc SvcCtx"); 
    } 

    /* Allocate Server Handle */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIServer, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIHandleAlloc Server"); 
    } 

    /* Set Server into ServerContext */ 
    errno = OCIAttrSet( (dvoid *)this ->m_pOCISvcCtx, OCI_HTYPE_SVCCTX, (dvoid *)this ->m_pOCIServer, 0, OCI_ATTR_SERVER, (OCIError *)this ->m_pOCIError); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIAttrSet Server"); 
    } 

    /* Attach Server */ 
    errno = OCIServerAttach(this ->m_pOCIServer, this ->m_pOCIError, (text *)this ->m_sDBName, strlen(this ->m_sDBName), OCI_DEFAULT); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIServerAttach"); 
    } 

    /* Allocate Session Handle */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCISession, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIHandleAlloc Session"); 
    } 

    /* Set Session into ServerContext */ 
    errno = OCIAttrSet( (dvoid *)this ->m_pOCISvcCtx, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)this ->m_pOCISession, (ub4)0, (ub4)OCI_ATTR_SESSION, (OCIError *)this ->m_pOCIError); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIAttrSet Session"); 
    } 

    /* Set Session UserName */ 
    errno = OCIAttrSet( (dvoid *)this ->m_pOCISession, OCI_HTYPE_SESSION, (dvoid *)this ->m_sUser, strlen(this ->m_sUser), OCI_ATTR_USERNAME, (OCIError *)this ->m_pOCIError); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIAttrSet UserName"); 
    } 

    /* Set Session Password */ 
    errno = OCIAttrSet( (dvoid *)this ->m_pOCISession, OCI_HTYPE_SESSION, (dvoid *)this ->m_sPwd, (ub4)strlen(this ->m_sPwd), (ub4)OCI_ATTR_PASSWORD, (OCIError *)this ->m_pOCIError); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::Multiple_Conn OCIAttrSet Password"); 
    } 

    /* Session Begin */ 
    errno = OCISessionBegin(this ->m_pOCISvcCtx, this ->m_pOCIError, this ->m_pOCISession, OCI_CRED_RDBMS, OCI_DEFAULT); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::Multiple_Conn OCISessionBegin"); 
    } 
    return 0; 
  } 
  catch (OCIException &ex) 
  { 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


void OCIDB::Multiple_Disc() 

  sword errno; 

  /* End Session */ 
  errno = OCISessionEnd(this ->m_pOCISvcCtx, this ->m_pOCIError, this ->m_pOCISession, (ub4)OCI_DEFAULT); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCISessionEnd"); 
  } 

  /* Free Session */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCISession, (ub4)OCI_HTYPE_SESSION ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIHandleFree Session"); 
  } 

  /* Detach Server */ 
  errno = OCIServerDetach(this ->m_pOCIServer, this ->m_pOCIError, OCI_DEFAULT); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIServerDetach"); 
  } 

  /* Free Server */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCIServer, (ub4)OCI_HTYPE_SERVER ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIHandleFree Server"); 
  } 

  /* Free ServerContext */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCISvcCtx, (ub4)OCI_HTYPE_SVCCTX ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIHandleFree ServerContext"); 
  } 

  /* Free Error */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCIError, (ub4)OCI_HTYPE_ERROR ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIHandleFree Error"); 
  } 

  /* Free Env */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCIEnv, (ub4)OCI_HTYPE_ENV ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::Multiple_Disc OCIHandleFree Env"); 
  } 


int OCIDB::ExcuteSQL(char * sql) 

  sword errno; 
  try 
  { 
    /* Allocate Stmt */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIStmt, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCIHandleAlloc"); 
    } 

    errno = OCIStmtPrepare(this ->m_pOCIStmt, this ->m_pOCIError, (const OraText *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCIStmtPrepare"); 
    } 

    errno = OCIStmtExecute(this ->m_pOCISvcCtx, this ->m_pOCIStmt, this ->m_pOCIError, (ub4)1, (ub4)0, (const OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCIStmtExecute"); 
    } 

    errno = OCITransCommit( this ->m_pOCISvcCtx, this ->m_pOCIError, 0); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCITransCommit"); 
    } 

    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCIHandleFree"); 
    } 
    return 0; 
  } 
  catch (OCIException &ex) 
  { 
    /* Rollback */ 
    errno = OCITransRollback( this ->m_pOCISvcCtx, this ->m_pOCIError, 0); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCITransRollback"); 
    } 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::ExcuteSQL OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


void OCIDB::BindInitVars() 

  int i; 
  for( i = 0 ; i < MAX_BINDVAR_COUNT - 1 ; i++ ) 
  { 
    this ->m_BindVars[i].VarType = 0; 
    this ->m_BindVars[i].VarName = 0; 
    this ->m_BindVars[i].VarLen = 0; 
    this ->m_BindVars[i].ValueChar = 0; 
  } 
  this ->m_iBindVarsCount = 0; 


void OCIDB::BindClearVars() 

  int i; 
  for( i = 0 ; i < m_iBindVarsCount - 1 ; i++ ) 
  { 
    delete [] this ->m_BindVars[i].VarName; 
    if ( this ->m_BindVars[i].VarType == SQLT_STR ) 
      delete [] this ->m_BindVars[i].ValueChar; 
    if ( this ->m_BindVars[i].VarType == SQLT_INT ) 
      delete [] this ->m_BindVars[i].ValueInt; 

    this ->m_BindVars[i].VarType = 0; 
    this ->m_BindVars[i].VarName = 0; 
    this ->m_BindVars[i].VarLen = 0; 
    this ->m_BindVars[i].ValueChar = 0; 
  } 
  this ->m_iBindVarsCount = 0; 


void OCIDB::BindAddVar(char * name, char * value) 

  if ( this ->m_iBindVarsCount >= MAX_BINDVAR_COUNT ) 
    return; 
  this ->m_BindVars[this ->m_iBindVarsCount].VarType = SQLT_STR; 
  this ->m_BindVars[this ->m_iBindVarsCount].VarName = new char[strlen(name) + 1]; 
  strcpy( this ->m_BindVars[this ->m_iBindVarsCount].VarName, name); 

  this ->m_BindVars[this ->m_iBindVarsCount].ValueChar = new char[strlen(value) + 1]; 
  strcpy( this ->m_BindVars[this ->m_iBindVarsCount].ValueChar, value); 
  this ->m_BindVars[this ->m_iBindVarsCount].VarLen = strlen(value) + 1; 

  this ->m_iBindVarsCount++; 


void OCIDB::BindAddVar(char * name, int * value) 

  if ( this ->m_iBindVarsCount >= MAX_BINDVAR_COUNT ) 
    return; 
  this ->m_BindVars[this ->m_iBindVarsCount].VarType = SQLT_INT; 
  this ->m_BindVars[this ->m_iBindVarsCount].VarName = new char[strlen(name) + 1]; 
  strcpy( this ->m_BindVars[this ->m_iBindVarsCount].VarName, name); 

  this ->m_BindVars[this ->m_iBindVarsCount].ValueInt = new int; 
  this ->m_BindVars[this ->m_iBindVarsCount].ValueInt = value; 
  this ->m_BindVars[this ->m_iBindVarsCount].VarLen = sizeof(int); 

  this ->m_iBindVarsCount++; 


int OCIDB::BindSQL(char * sql) 

  if( this ->m_iBindVarsCount == 0 ) 
    return -1; 
  sword errno; 
  try 
  { 
    /* Allocate Stmt */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIStmt, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::BindSQL OCIHandleAlloc Stmt"); 
    } 
    /* Prepare Stmt */ 
    errno = OCIStmtPrepare( this ->m_pOCIStmt, this ->m_pOCIError, (const OraText *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::BindSQL OCIStmtPrepare"); 
    } 
    /* Bind Vars */ 
    int i; 
    for ( i = 0 ; i < m_iBindVarsCount - 1 ; i++ ) 
    { 
      /* Bind By Name */ 
      errno = OCIBindByName( this ->m_pOCIStmt, &this ->m_pOCIBind, this ->m_pOCIError, (text *)this ->m_BindVars[i].VarName, -1, 
          (dvoid *)this ->m_BindVars[i].ValueChar, this ->m_BindVars[i].VarLen, this ->m_BindVars[i].VarType, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT); 

      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::BindSQL OCIBindByName"); 
      } 
      /* 
      errno = OCIBindByPos( this ->m_pOCIStmt, &this ->m_pOCIBind, this ->m_pOCIError, i + 1, (dvoid *)this ->m_BindVars[i].ValueChar, 
          this ->m_BindVars[i].VarLen, this ->m_BindVars[i].VarType, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT); 

      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::BindSQL OCIBindByPos"); 
      } 
      */ 
    } 
    /* Execute SQL */ 
    errno = OCIStmtExecute( this ->m_pOCISvcCtx, this ->m_pOCIStmt, this ->m_pOCIError, (ub4)1, (ub4)0, (const OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::BindSQL OCIStmtExecute"); 
    } 
    /*  Commit */ 
    errno = OCITransCommit( this ->m_pOCISvcCtx, this ->m_pOCIError, 0); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::BindSQL OCITransCommit"); 
    } 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::BindSQL OCIHandleFree"); 
    } 
    /* Clear Vars */ 
    this ->BindClearVars(); 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Rollback */ 
    errno = OCITransRollback( this ->m_pOCISvcCtx, this ->m_pOCIError, 0); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::BindSQL OCITransRollback"); 
    } 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::BindSQL OCIHandleFree"); 
    } 
    this ->BindClearVars(); 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserPrepare(char * sql) 

  sword errno; 
  try 
  { 
    /* Allocate Stmt */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIStmt, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 ); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::UserPrepare OCIHandleAlloc"); 
    } 
    /* Prepare Stmt */ 
    errno = OCIStmtPrepare( this ->m_pOCIStmt, this ->m_pOCIError, (const OraText *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, (char *)"OCIDB::UserPrepare OCIStmtPrepare"); 
    } 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::UserPrepare Ex OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserFree() 

  sword errno; 
  /* Free Stmt */ 
  errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::UserFree OCIHandleFree"); 
    return -1; 
  } 
  return 0; 


int OCIDB::UserBind(char * name, char * value) 

  sword errno; 
  try 
  { 
    errno = OCIBindByName( this ->m_pOCIStmt, &this ->m_pOCIBind, this ->m_pOCIError, (text *)name, -1, 
        (dvoid *)value, strlen(value) + 1, SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserBind OCIBindByName"); 
    } 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::UserBind Ex OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserBind(char * name, int value) 

  sword errno; 
  try 
  { 
    int val = value; 
    errno = OCIBindByName( this ->m_pOCIStmt, &this ->m_pOCIBind, this ->m_pOCIError, (text *)name, -1, 
        (dvoid *)&val, sizeof(int), SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserBind OCIBindByName"); 
    } 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::UserBind Ex OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserExecute() 

  sword errno; 
  try 
  { 
    errno = OCIStmtExecute( this ->m_pOCISvcCtx, this ->m_pOCIStmt, this ->m_pOCIError, (ub4)1, (ub4)0, 
        (const OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserExecute OCIBindByName"); 
    } 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::UserExecute Ex OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserCommit() 

  sword errno; 
  errno = OCITransCommit( this ->m_pOCISvcCtx, this ->m_pOCIError, 0); 
  if ( errno ) 
  { 
    OCIError::PrintError(errno, (char *)"OCIDB::UserCommit OCITransCommit"); 
    return -1; 
  } 
  return 0; 


int OCIDB::UserSelect(char * sql) 

  sword errno; 
  try 
  { 
    /* Allocate Stmt */ 
    errno = OCIHandleAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_pOCIStmt, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIHandleAlloc"); 
    } 
    /* Prepare Stmt */ 
    errno = OCIStmtPrepare( this ->m_pOCIStmt, this ->m_pOCIError, (const OraText *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIStmtPrepare"); 
    } 
    /* Execute Stmt */ 
    errno = OCIStmtExecute( this ->m_pOCISvcCtx, this ->m_pOCIStmt, this ->m_pOCIError, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIStmtExecute"); 
    } 

    errno = OCIAttrGet( this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT, (dvoid *)&this ->m_iSelectVarsCount, (ub4 *)0, (ub4)OCI_ATTR_PARAM_COUNT, this ->m_pOCIError ); 
    if ( errno ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet"); 
    } 
    int iLen; 
    char * sName; 
    ub2 iSize, iPrecision, iType; 
    ub1 iScale, iIsNull; 

    int i; 
    for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
    { 
      sName = 0; 
      errno = OCIParamGet( this ->m_pOCIStmt, OCI_HTYPE_STMT, this ->m_pOCIError, (dvoid **)&this ->m_pOCIParam, i+ 1 ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIParamGet"); 
      } 
      //  Column Name 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid **)&sName, (ub4 *)&iLen, OCI_ATTR_NAME, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Column Name"); 
      } 
      strncpy( this ->m_SelectVars[i].VarName, sName, iLen ); 
      this ->m_SelectVars[i].VarName[iLen] = 0; 
      //  Data Size; 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid *)&iSize, (ub4 *)0, OCI_ATTR_DATA_SIZE, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Data Size");
      } 
      this ->m_SelectVars[i].VarSize = iSize; 
      //  Data Precision 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid *)&iPrecision, (ub4 *)0, OCI_ATTR_PRECISION, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Data Precision"); 
      } 
      this ->m_SelectVars[i].VarPrecision = iPrecision; 
      //  Data Scale 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid *)&iScale, (ub4 *)0, OCI_ATTR_SCALE, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Data Scale"); 
      } 
      this ->m_SelectVars[i].VarScale = iScale; 
      //  Data Is Null 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid *)&iIsNull, (ub4 *)0, OCI_ATTR_IS_NULL, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Data Is Null"); 
      } 
      this ->m_SelectVars[i].VarIsNull = iIsNull; 
      //  Data Type 
      errno = OCIAttrGet( (dvoid *)this ->m_pOCIParam, OCI_DTYPE_PARAM, (dvoid *)&iType, (ub4 *)0, OCI_ATTR_DATA_TYPE, this ->m_pOCIError ); 
      if ( errno ) 
      { 
        throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIAttrGet Data Type"); 
      } 
      this ->m_SelectVars[i].VarType = iType; 

      switch ( this ->m_SelectVars[i].VarType ) 
      { 
      case SQLT_NUM: 
        if ( this ->m_SelectVars[i].VarScale == 0 ) 
        { 
          this ->m_SelectVars[i].ValueInt = new int; 
          this ->m_SelectVars[i].VarType = TYPE_INT; 
          errno = OCIDefineByPos( this ->m_pOCIStmt, &this ->m_pOCIDefine, this ->m_pOCIError, i + 1, 
              (dvoid *)this ->m_SelectVars[i].ValueInt,  sizeof(int), SQLT_INT, this ->indp, (ub2 *)0, (ub2 *)0, OCI_DEFAULT ); 
          if ( errno ) 
          { 
            throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDefineByPos"); 
          } 
        } 
        else 
        { 
          this ->m_SelectVars[i].ValueFloat = new float; 
          this ->m_SelectVars[i].VarType = TYPE_FLOAT; 
          errno = OCIDefineByPos( this ->m_pOCIStmt, &this ->m_pOCIDefine, this ->m_pOCIError, i + 1, 
              (dvoid *)this ->m_SelectVars[i].ValueFloat,  sizeof(float), SQLT_FLT, this ->indp, (ub2 *)0, (ub2 *)0, OCI_DEFAULT ); 
          if ( errno ) 
          { 
            throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDefineByPos"); 
          } 
        } 
        break; 
      case SQLT_CHR: 
        this ->m_SelectVars[i].ValueChar = new char[this ->m_SelectVars[i].VarSize + 1]; 
        this ->m_SelectVars[i].VarType = TYPE_STRING; 
        errno = OCIDefineByPos( this ->m_pOCIStmt, &this ->m_pOCIDefine, this ->m_pOCIError, i + 1, 
            (dvoid *)this ->m_SelectVars[i].ValueChar,  this ->m_SelectVars[i].VarSize + 1, SQLT_STR, this ->indp, (ub2 *)0, (ub2 *)0, OCI_DEFAULT ); 
        if ( errno ) 
        { 
          throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDefineByPos"); 
        } 
        break; 
      case SQLT_BLOB: 
        /* Allocate lobLocator */ 
        errno = OCIDe.orAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_SelectVars[i].lobLocator, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0 ); 
        if ( errno ) 
        { 
          throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDe.orAlloc"); 
        } 
        this ->m_SelectVars[i].VarType = TYPE_BLOB; 
        errno = OCIDefineByPos( this ->m_pOCIStmt, &this ->m_pOCIDefine, this ->m_pOCIError, (ub4)i + 1, (dvoid *)&this ->m_SelectVars[i].lobLocator, (sb4)0, 
            (ub2)SQLT_BLOB, this ->indp, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT); 
        if ( errno ) 
        { 
          throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDefineByPos"); 
        } 
        break; 
      case SQLT_CLOB: 
        /* Allocate lobLocator */ 
        errno = OCIDe.orAlloc( (dvoid *)this ->m_pOCIEnv, (dvoid **)&this ->m_SelectVars[i].lobLocator, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0 ); 
        if ( errno ) 
        { 
          throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDe.orAlloc"); 
        } 
        this ->m_SelectVars[i].VarType = TYPE_BLOB; 
        errno = OCIDefineByPos( this ->m_pOCIStmt, &this ->m_pOCIDefine, this ->m_pOCIError, (ub4)i + 1, (dvoid *)&this ->m_SelectVars[i].lobLocator, (sb4)0, 
            (ub2)SQLT_BLOB, this ->indp, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT); 
        if ( errno ) 
        { 
          throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserSelect OCIDefineByPos"); 
        } 
        break; 
      } 
    } 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    /* Free Stmt */ 
    errno = OCIHandleFree( (dvoid *)this ->m_pOCIStmt, (ub4)OCI_HTYPE_STMT ); 
    if ( errno ) 
    { 
      OCIError::PrintError(errno, (char *)"OCIDB::UserExecute Ex OCIHandleFree"); 
    } 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserFetch() 

  sword errno; 
  try 
  { 
    errno = OCIStmtFetch( this ->m_pOCIStmt, this ->m_pOCIError, 1, OCI_FETCH_NEXT, OCI_DEFAULT ); 
    if ( errno && errno != OCI_NO_DATA ) 
    { 
      throw OCIException(errno, this ->m_pOCIError, (char *)"OCIDB::UserFetch OCIStmtFetch"); 
    } 
    if ( errno == OCI_NO_DATA ) 
      return 1; 
    return 0; 
  } 
  catch ( OCIException &ex ) 
  { 
    std::cout << ex.GetErrFunc() << ex.GetErrMsg() << std::endl; 
    return -1; 
  } 


int OCIDB::UserSelectFree() 

  int i; 
  for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
  { 
    switch ( this ->m_SelectVars[i].VarType ) 
    { 
    case TYPE_STRING: 
      delete [] this ->m_SelectVars[i].ValueChar; 
      break; 
    case TYPE_FLOAT: 
      delete this ->m_SelectVars[i].ValueFloat; 
      break; 
    case TYPE_INT: 
      delete this ->m_SelectVars[i].ValueInt; 
      break; 
    } 
  } 
  return this ->UserFree(); 


int OCIDB::UserGetInt(int index) 

  switch ( this ->m_SelectVars[index].VarType ) 
  { 
  case TYPE_FLOAT: 
    return (int)*m_SelectVars[index].ValueFloat; 
    break; 
  case TYPE_INT: 
    return *m_SelectVars[index].ValueInt; 
    break; 
  default: 
    return 0; 
  } 


int OCIDB::UserGetInt(char * name) 

  int i; 
  for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
  { 
    if ( this ->StrCmp(m_SelectVars[i].VarName, name) ) 
    { 
      switch ( this ->m_SelectVars[i].VarType ) 
      { 
      case TYPE_FLOAT: 
        return (int)*m_SelectVars[i].ValueFloat; 
        break; 
      case TYPE_INT: 
        return *m_SelectVars[i].ValueInt; 
        break; 
      default: 
        return 0; 
      } 
    } 
  } 
  return 0; 


float OCIDB::UserGetFloat(int index) 

  switch ( this ->m_SelectVars[index].VarType ) 
  { 
  case TYPE_FLOAT: 
    return *m_SelectVars[index].ValueFloat; 
    break; 
  case TYPE_INT: 
    return (float)*m_SelectVars[index].ValueInt; 
    break; 
  default: 
    return 0; 
  } 


float OCIDB::UserGetFloat(char * name) 

  int i; 
  for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
  { 
    if ( this ->StrCmp(m_SelectVars[i].VarName, name) ) 
    { 
      switch ( this ->m_SelectVars[i].VarType ) 
      { 
      case TYPE_FLOAT: 
        return *m_SelectVars[i].ValueFloat; 
        break; 
      case TYPE_INT: 
        return (float)*m_SelectVars[i].ValueInt; 
        break; 
      default: 
        return 0; 
      } 
    } 
  } 
  return 0; 


char * OCIDB::UserGetString(int index) 

  if ( this ->m_SelectVars[index].VarType == TYPE_STRING ) 
  { 
    return this ->m_SelectVars[index].ValueChar; 
  } 
  else 
  { 
    return 0; 
  } 


char * OCIDB::UserGetString(char * name) 

  int i; 
  for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
  { 
    if ( this ->StrCmp(m_SelectVars[i].VarName, name) ) 
    { 
      if ( this ->m_SelectVars[i].VarType == TYPE_STRING ) 
      { 
        return this ->m_SelectVars[i].ValueChar; 
      } 
    } 
  } 
  return 0; 


char * OCIDB::UserGetBlob(int index) 

  if ( this ->m_SelectVars[index].VarType == TYPE_BLOB ) 
  { 
    return this ->m_SelectVars[index].ValueChar; 
  } 
  else 
  { 
    return 0; 
  } 


char * OCIDB::UserGetBlob(char * name) 

  int i; 
  for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
  { 
    if ( this ->StrCmp(m_SelectVars[i].VarName, name) ) 
    { 
      if ( this ->m_SelectVars[i].VarType == TYPE_BLOB ) 
      { 
        return this ->m_SelectVars[i].ValueChar; 
      } 
    } 
  } 
  return 0; 


vector< vector<string> > OCIDB::getResult() 

  int i; 
  vector<string> objectValue; 
  StringTools stringTools; 
  while ( this ->UserFetch() == 0 ) 
  { 
    objectValue.clear(); 
    for ( i = 0 ; i < this ->m_iSelectVarsCount ; i++ ) 
    { 
      switch ( this ->m_SelectVars[i].VarType ) 
      { 
      case TYPE_STRING: 
        objectValue.push_back(this ->UserGetString(i)); 
        break; 
      case TYPE_FLOAT: 
        objectValue.push_back(stringTools.ToString(this ->UserGetFloat(i))); 
        break; 
      case TYPE_INT: 
        objectValue.push_back(stringTools.ToString(this ->UserGetInt(i))); 
        break; 
      case TYPE_BLOB: 
        break; 
      } 
    } 
    resultList.push_back(objectValue); 
  } 

  return resultList; 


void inline OCIDB::StrUpper(char * str) 

  int i; 
  int sLen = strlen(str); 
  for ( i = 0 ; i < sLen ; i++ ) 
  { 
    str[i] = toupper(str[i]); 
  } 


bool inline OCIDB::StrCmp(const char * ori, const char * des) 

  int iLenOri, iLenDes; 
  int j; 

  iLenOri = strlen(ori); 
  iLenDes = strlen(des); 

  if ( iLenOri != iLenDes ) 
    return false; 

  for ( j = 0 ; j < iLenOri ; j++ ) 
  { 
    if ( toupper(ori[j]) != toupper(des[j]) ) 
    { 
      return false; 
    } 
  } 
  return true; 

五、修改建议
本套代码只是处理了LOB类型的绑定,没有处理LOB类型数据的读取。
本人在以后的完善中,打算把runSQLCommand(char * sql)函数分解成两个或者三个函数,分别执行select和insert等语句。
在程序中,我并没有强制要求参数必须为const,可能会出现一些安全问题。
本文仅起抛砖引玉的作用,希望有高手可以指点我程序中的问题。

本文出自 “玄武·巴依” 博客,转载请与作者联系!





你可能感兴趣的:(Linux下使用C/C++访问数据库——Oracle之OCI篇)