C/C++访问数据库——Oracle之OCI篇

本文详细介绍了在Linux环境下,如何利用C/C++编程语言通过Oracle Call Interface (OCI)与Oracle数据库进行交互,包括设置环境、处理异常、建立会话以及执行SQL语句等关键步骤。
摘要由CSDN通过智能技术生成

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_D
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值