ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Linux 下进行 OCCI ( Oracle C++ Call Interface ) 开发

2020-02-20 14:44:48  阅读:249  来源: 互联网

标签:string C++ Oracle Call 11.2 OCCI Interface using root


Linux 下进行 OCCI ( Oracle C++ Call Interface ) 开发

Oracle 调用接口 (Orale Call Interface,OCI) 是最全面、性能最高、基于原生“C”语言的 Oracle 数据库接口,它可以提供 Oracle 数据库的全部功能。

OCI 为构建各种语言专用接口(如 Oracle JDBC-OCI、ODP.Net、Oracle 预编译器、Oracle ODBC 和 Oracle C++ Call Interface (OCCI)驱动程序)提供了基础。

使用C/C++操作Oracle数据库,我们经常采用 Oracle C++ Call Interface (OCCI) 来进行编程,下面介绍 Linux 下如何做 OCCI 开发.

要在Linux 下做 OCCI 开发,首先必须在开发机器上安装有 OCCI 相关库(包含开发所需的库和运行所需的库)和头文件, OCCI 库和头文件可以通过以下三种途径得到:

(1) 安装 Oracle 数据库引擎

(2) 安装 Oracle Client

(3) 安装 Oracle Instant Client.

其中,前两种方式下,

库所在位置一般是:$(ORACLE_HOME)/product/11.2.0.1.0/db_1/lib

头文件所在位置一般是:$(ORACLE_HOME)/product/11.2.0.1.0/db_1/rdbms/public/

只要安装了Oracle数据库引擎或者客户端,库文件和头文件就能够很方便的得到。然而,通常我们的开发都是安装一台数据库服务器,然后在客户机器上做开发,所以安装Oracle数据库引擎不可取,鉴于安装Oracle Client也相对比较繁琐,我们采用第三种方式可以减少很多不必要的工作。尽管如此,我们还是有必要首先简单介绍在前两种方式下如何做OCCI开发。

(1) OCCI 开发方式一

** (i)编译**

   编写好程序后,Makefile 定义相关变量,然后进行编译,例如:
OCCI_HOME= /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1

       OCCI_INCLUDE_DIR=$(OCCI_HOME)/rdbms/public/

       OCCI_LIBRARY_PATH=$(OCCI_HOME)/lib

      default:

g++ *.cpp  -I$(OCCI_INCLUDE_DIR)  -L$(OCCI_LIBRARY_PATH)  -locci  -lclntsh

** (ii)运行**

   编译完成后,运行程序,运行OCCI程序必须设置以下环节变量:
    export ORACLE_BASE=/sdb1/oracle/11gR2_database_X64
       export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.1.0/db_1
       export NLS_LANG='simplified chinese'_china.ZHS16GBK
       export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

** (iii) 附加问题**

   若想将OCCI头文件和库文件拷贝到其它机器进行OCCI开发,则按如下步骤做,参照http://blog.csdn.net/zklth/article/details/7184032 :

(1) 方法一:使用 Oracle 11.2.0.1 数据库软件中自带的 OCCI 相关库和头文件.
在一个安装好Oracle 11.2.0.1 R2 数据库的机器上拷贝occi相关头文件和库文件到目录 /opt/OCCI_11g_R2/include 和 /opt/OCCI_11g_R2/lib 下,

头文件:
mkdir  /opt/OCCI_11g_R2/include
cp -r /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/rdbms/public/*     /opt/OCCI_11g_R2/include/
库文件:
mkdir  /opt/OCCI_11g_R2/lib
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libclntsh.so.11.1    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libocci.so.11.1    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libocci11.a    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.so    /opt/OCCI_11g_R2/lib/
cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.a   /opt/OCCI_11g_R2/lib/
cd /opt/OCCI_11g_R2/lib
创建3个软链接
ln -s libocci.so.11.1  libocci.so
ln -s libclntsh.so.11.1   libclntsh.so
ln -s libclntsh.so libclntsh.so.10.1  
[root@localhost lib]# ll
总计 69764
lrwxrwxrwx 1 root root       17 01-07 13:33 libclntsh.so -> libclntsh.so.11.1
lrwxrwxrwx 1 root root       12 01-07 13:33 libclntsh.so.10.1 -> libclntsh.so
-rwxr-xr-x 1 root root 48724689 01-07 12:58 libclntsh.so.11.1
-rw-r--r-- 1 root root 11595642 2012-01-07 libnnz11.a
-rw-r--r-- 1 root root  7899997 2012-01-07 libnnz11.so
-rw-r--r-- 1 root root  1863334 01-07 12:50 libocci11.a
lrwxrwxrwx 1 root root       15 01-07 13:33 libocci.so -> libocci.so.11.1
-rwxr-xr-x 1 root root  1260923 01-07 12:50 libocci.so.11.1

编译OCCI程序时使用如下选项:
OCCI_HOME=/opt/OCCI_11g_R2
OCCI_INCLUDE_DIR=$(OCCI_HOME)/include
OCCI_LIBRARY_PATH=$(OCCI_HOME)/lib
g++ *.cpp  -I$(OCCI_INCLUDE_DIR)  -L$(OCCI_LIBRARY_PATH)  -locci  -lclntsh  -lnnz11      # 注意要加上 lnnz11,libclntsh.so 中使用到了 libnnz11.so 中的函数.

编译成功!

(2) 安装 ORACLE Instant Client 做 OCCI 开发
(i) 安装ORACLE Instant Client

        安装请参见帖  http://blog.csdn.net/zklth/article/details/7190035   或者 http://blog.csdn.net/zklth/article/details/7184032

        包含 zip 安装 和 rpm 安装.  注意,做开发必须安装 basic、sdk 两个包.

        对于 zip 包.

        开发相关的头文件在:/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2/sdk/include

        开发相关的库文件在:/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2.

        对于rpm包

        开发相关的头文件在:/usr/include/oracle/11.2/client64

        开发相关的库文件在:/usr/lib/oracle/11.2/client64/lib

        安装完毕,进入库文件所在目录,创建如下2个软链接:
        ln -s libclntsh.so.11.1 libclntsh.so

        ln -s libocci.so.11.1 libocci.so

** (ii) 编译 OCCI 程序**

         这里以zip安装为例, Oracle Instant Client 安装路径是:/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2.

         Makefile 按如下方式书写.
OCCI_INCLUDE_DIR=/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2/sdk/include
OCCI_LIBRARY_PATH=/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2
 
default:
    g++ -o test test.cpp DBwrapper.cpp -I$(OCCI_INCLUDE_DIR) -L$(OCCI_LIBRARY_PATH) -locci -lclntsh
 (iii)运行

   编译完成后,运行程序,运行OCCI程序必须设置以下环节变量:

   export ORACLE_HOME=/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2
   export NLS_LANG='simplified chinese'_china.ZHS16GBK
   export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH

   建议写一个脚本运行程序,在脚本中设置这些环境变量.

附: 示例代码

//
// File: DBwrapper.h
// Author: zhankunlin
// Date: 2011-12-6
// Desc: Operate database.
//
 
#ifndef DBOP_H
#define DBOP_H
 
#include<string>
#include<map>
#include<vector>
using std::string;
using std::map;
using std::vector;
 
#include "occi.h"
using oracle::occi::Environment;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::SQLException;
 
class DBwrapper
{
public:
	DBwrapper();
	DBwrapper(string confFilePath);
	DBwrapper(string user, string pwd, string conStr);
	~DBwrapper();
	void readConfFile();
	bool open(); 
	bool close();
	bool commit();
	void setSQL(string oneSQL);
	bool execSQL(string sqlStr, string op);
	bool execQuerySQL();
	Statement* getStatement();
 	ResultSet* getResultSet();
	bool execUpdateSQL();
	bool execBatchedUpdate();
	
	void generateSQL(map<string, string> oneSQLKV); /* generate one SQL string */	
//	vector<string> generateSQL(vector<map<string, string>> multiSql); /* generate multiple SQL string */	
	map<string, string> execSQL(string strSQL); /* execute one SQL string */
//	vector<map<string, string>> execSQL(vector<string> strSQLs); /* execute multiple SQL string */
 
private:
	Environment *env; /* in $ORACLE_HOME/rdbms/public/occiControl.h */
	Connection *conn;
	Statement *stmt;
 	ResultSet *rs;
	
	string strSQL;
	string user;
	string password;
	string conStr;
 
	string confFilePath;
};
 
#endif
//
// File: DBwrapper.cpp
// Author: zhankunlin
// Date: 2011-12-6
// Desc: Operate database.
//
 
#include "DBwrapper.h"
 
#include<iostream>
#include<string>
#include<map>
#include<vector>
using std::string;
using std::map;
using std::vector;
using std::cout;
using std::endl;
using std::ios;
 
#include <fstream>
using std::ifstream;
 
#include "occi.h"
using oracle::occi::Environment;
using oracle::occi::Connection;
using oracle::occi::Statement;
using oracle::occi::ResultSet;
using oracle::occi::SQLException;
 
DBwrapper::DBwrapper()
{
	this->confFilePath = "conf//server.conf";
	readConfFile();
}
 
DBwrapper::DBwrapper(string confFilePath)
{
	this->confFilePath = confFilePath;
	readConfFile();
}
 
DBwrapper::DBwrapper(string user, string pwd, string conStr)
{
	this->user = user;
	this->password = pwd;
	this->conStr = conStr;
}
 
void DBwrapper::readConfFile()
{
	ifstream configFile(this->confFilePath.c_str(), ios::in); 
	if( !configFile.is_open() ) {
		cout<< "Open file "<< this->confFilePath << " failed!" <<endl;
		return;
	}
	
	string line, name, value;
	int len=0, start=0;
		
	while( configFile >> line )
	{
		if( line.find('#') != string::npos ) /* annotation */
			continue;
		if( line.find("=") == string::npos ) /* not found = */
			continue;
		len=line.length();
		start=line.find("="); /* = 的下标 */
		name=line.substr(0, start);
		value=line.substr(start+1, len-(start+1));
 
		if(name == "db_user") {
			this->user = value;
		}
 
		if(name == "db_user_pwd") {
			this->password = value;
		}
 
		if(name == "db_con_str") {
			this->conStr = value;
		}
 
	}
 
        cout<< "--------  Read configure file   -------" <<endl;
	cout<< "file: " << this->confFilePath <<endl; 
        cout<< "db_user: " << user <<endl;
        cout<< "db_user_pwd: " << password <<endl;
        cout<< "db_con_str: " << conStr <<endl;
        cout<< "---------------------------------------" <<endl;
}
 
DBwrapper::~DBwrapper()
{
	
}
 
//
// Desc:
//   Open connection to Oracle database.
// Return:
//   true  -- Successful.
//   false -- Failed.
//
bool DBwrapper::open()
{
	try {
		env = Environment::createEnvironment(Environment::OBJECT);	
		conn = env->createConnection(user, password, conStr);
		stmt = conn->createStatement();
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
//
// Desc:
//   Close connection to Oracle database.
// Return:
//   true  -- Successful.
//   false -- Failed.
//
bool DBwrapper::close()
{
	try {
		env->terminateConnection(conn);
		Environment::terminateEnvironment(env);
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
//
// Desc:
//   commit the operation.
// Return:
//   true  -- Successful.
//   false -- Failed.
//
bool DBwrapper::commit()
{
	try {
		conn->commit();
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
void DBwrapper::setSQL(string oneSQL)
{
	strSQL = oneSQL;
}
 
/* generate one SQL string */	
void DBwrapper::generateSQL(map<string, string> oneSQLKV) 
{
	string oneSQL="";
	strSQL = oneSQL;
}
 
bool DBwrapper::execBatchedUpdate()
{
	try {	
		stmt->executeUpdate();
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
bool DBwrapper::execUpdateSQL()
{
	try {	
		stmt->setSQL(strSQL);
		stmt->executeUpdate();
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
bool DBwrapper::execQuerySQL()
{
	try {
		stmt->setSQL(strSQL);
		rs = stmt->executeQuery();
	} catch (SQLException ex) {
		cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();
		return false;
	}
	return true;
}
 
ResultSet* DBwrapper::getResultSet()
{
	return rs;
}
 
Statement* DBwrapper::getStatement()
{
	return stmt;
}
 
//
// Desc:
//   execute SQL string.
// Parameters:
//   string sqlStr -- SQL string
//   string op -- it has only four value.
//                insert, update, delete, select
//
bool DBwrapper::execSQL(string sqlStr, string op)
{	
	if(!(op == "insert" || op == "update" || 
	   op == "delete" || op == "select")) {
		cout<<"SQL operation must be in 'insert, update, delete, select'!"<<endl;
		return false;	
	}
	strSQL = sqlStr;
	if(op == "select") 
		return execQuerySQL();
	else
		return execUpdateSQL();
}
a1003930343 发布了6 篇原创文章 · 获赞 0 · 访问量 1522 私信 关注

标签:string,C++,Oracle,Call,11.2,OCCI,Interface,using,root
来源: https://blog.csdn.net/qq_32562005/article/details/104410293

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有