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

2023-11-11 06:18

本文主要是介绍Linux下使用C/C++访问数据库——Oracle之OCI篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Linux下使用C/C++访问数据库——Oracle之OCI篇
2009-03-17 10:29:20
标签: C++ Linux Oracle 休闲 数据库
版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。
一、什么是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篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/388102

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间