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 库和头文件可以通过以下三种途径得到:

(i) 安装 Oracle 数据库引擎  (2) 安装 Oracle Client  (3) 安装 Oracle Instant Client.

其中,前两种方式下,

库所在位置一般是: /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib

头文件所在位置一般是: /sdd1/oracle/11gR2_database_X64/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 :

[plain]  view plain copy
  1. (1) 方法一:使用 Oracle 11.2.0.1 数据库软件中自带的 OCCI 相关库和头文件.  
  2. 在一个安装好Oracle 11.2.0.1 R2 数据库的机器上拷贝occi相关头文件和库文件到目录 /opt/OCCI_11g_R2/include 和 /opt/OCCI_11g_R2/lib 下,   
  3. 头文件:  
  4. mkdir  /opt/OCCI_11g_R2/include  
  5. cp -r /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/rdbms/public/*     /opt/OCCI_11g_R2/include/  
  6. 库文件:  
  7. mkdir  /opt/OCCI_11g_R2/lib  
  8. cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libclntsh.so.11.1    /opt/OCCI_11g_R2/lib/  
  9. cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/lib/libocci.so.11.1    /opt/OCCI_11g_R2/lib/  
  10. cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libocci11.a    /opt/OCCI_11g_R2/lib/  
  11. cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.so    /opt/OCCI_11g_R2/lib/  
  12. cp /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/libnnz11.a   /opt/OCCI_11g_R2/lib/  
  13. cd /opt/OCCI_11g_R2/lib  
  14. 创建3个软链接  
  15. ln -s libocci.so.11.1  libocci.so  
  16. ln -s libclntsh.so.11.1   libclntsh.so  
  17. ln -s libclntsh.so libclntsh.so.10.1    
  18. [root@localhost lib]# ll  
  19. 总计 69764  
  20. lrwxrwxrwx 1 root root       17 01-07 13:33 libclntsh.so -> libclntsh.so.11.1  
  21. lrwxrwxrwx 1 root root       12 01-07 13:33 libclntsh.so.10.1 -> libclntsh.so  
  22. -rwxr-xr-x 1 root root 48724689 01-07 12:58 libclntsh.so.11.1  
  23. -rw-r--r-- 1 root root 11595642 2012-01-07 libnnz11.a  
  24. -rw-r--r-- 1 root root  7899997 2012-01-07 libnnz11.so  
  25. -rw-r--r-- 1 root root  1863334 01-07 12:50 libocci11.a  
  26. lrwxrwxrwx 1 root root       15 01-07 13:33 libocci.so -> libocci.so.11.1  
  27. -rwxr-xr-x 1 root root  1260923 01-07 12:50 libocci.so.11.1  
  28.   
  29. 编译OCCI程序时使用如下选项:  
  30. OCCI_HOME=/opt/OCCI_11g_R2  
  31. OCCI_INCLUDE_DIR=$(OCCI_HOME)/include  
  32. OCCI_LIBRARY_PATH=$(OCCI_HOME)/lib  
  33. g++ *.cpp  -I$(OCCI_INCLUDE_DIR)  -L$(OCCI_LIBRARY_PATH)  -locci  -lclntsh  -lnnz11      # 注意要加上 lnnz11,libclntsh.so 中使用到了 libnnz11.so 中的函数.  
  34.   
  35. 编译成功!  


(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 按如下方式书写.

[python]  view plain copy
  1. OCCI_INCLUDE_DIR=/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2/sdk/include  
  2. OCCI_LIBRARY_PATH=/root/linux-11.2.0.1.0-1.x86_64/instantclient_11_2  
  3.   
  4. default:  
  5.     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

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

附:  示例代码

[cpp]  view plain copy
  1. <span style="font-size:13px;">//  
  2. // File: DBwrapper.h  
  3. // Author: zhankunlin  
  4. // Date: 2011-12-6  
  5. // Desc: Operate database.  
  6. //  
  7.   
  8. #ifndef DBOP_H  
  9. #define DBOP_H  
  10.   
  11. #include<string>  
  12. #include<map>  
  13. #include<vector>  
  14. using std::string;  
  15. using std::map;  
  16. using std::vector;  
  17.   
  18. #include "occi.h"  
  19. using oracle::occi::Environment;  
  20. using oracle::occi::Connection;  
  21. using oracle::occi::Statement;  
  22. using oracle::occi::ResultSet;  
  23. using oracle::occi::SQLException;  
  24.   
  25. class DBwrapper  
  26. {  
  27. public:  
  28.     DBwrapper();  
  29.     DBwrapper(string confFilePath);  
  30.     DBwrapper(string user, string pwd, string conStr);  
  31.     ~DBwrapper();  
  32.     void readConfFile();  
  33.     bool open();   
  34.     bool close();  
  35.     bool commit();  
  36.     void setSQL(string oneSQL);  
  37.     bool execSQL(string sqlStr, string op);  
  38.     bool execQuerySQL();  
  39.     Statement* getStatement();  
  40.     ResultSet* getResultSet();  
  41.     bool execUpdateSQL();  
  42.     bool execBatchedUpdate();  
  43.       
  44.     void generateSQL(map<string, string> oneSQLKV); /* generate one SQL string */   
  45. //  vector<string> generateSQL(vector<map<string, string>> multiSql); /* generate multiple SQL string */    
  46.     map<string, string> execSQL(string strSQL); /* execute one SQL string */  
  47. //  vector<map<string, string>> execSQL(vector<string> strSQLs); /* execute multiple SQL string */  
  48.   
  49. private:  
  50.     Environment *env; /* in $ORACLE_HOME/rdbms/public/occiControl.h */  
  51.     Connection *conn;  
  52.     Statement *stmt;  
  53.     ResultSet *rs;  
  54.       
  55.     string strSQL;  
  56.     string user;  
  57.     string password;  
  58.     string conStr;  
  59.   
  60.     string confFilePath;  
  61. };  
  62.   
  63. #endif  
  64. </span>  

[cpp]  view plain copy
  1. //  
  2. // File: DBwrapper.cpp  
  3. // Author: zhankunlin  
  4. // Date: 2011-12-6  
  5. // Desc: Operate database.  
  6. //  
  7.   
  8. #include "DBwrapper.h"  
  9.   
  10. #include<iostream>  
  11. #include<string>  
  12. #include<map>  
  13. #include<vector>  
  14. using std::string;  
  15. using std::map;  
  16. using std::vector;  
  17. using std::cout;  
  18. using std::endl;  
  19. using std::ios;  
  20.   
  21. #include <fstream>  
  22. using std::ifstream;  
  23.   
  24. #include "occi.h"  
  25. using oracle::occi::Environment;  
  26. using oracle::occi::Connection;  
  27. using oracle::occi::Statement;  
  28. using oracle::occi::ResultSet;  
  29. using oracle::occi::SQLException;  
  30.   
  31. DBwrapper::DBwrapper()  
  32. {  
  33.     this->confFilePath = "conf//server.conf";  
  34.     readConfFile();  
  35. }  
  36.   
  37. DBwrapper::DBwrapper(string confFilePath)  
  38. {  
  39.     this->confFilePath = confFilePath;  
  40.     readConfFile();  
  41. }  
  42.   
  43. DBwrapper::DBwrapper(string user, string pwd, string conStr)  
  44. {  
  45.     this->user = user;  
  46.     this->password = pwd;  
  47.     this->conStr = conStr;  
  48. }  
  49.   
  50. void DBwrapper::readConfFile()  
  51. {  
  52.     ifstream configFile(this->confFilePath.c_str(), ios::in);   
  53.     if( !configFile.is_open() ) {  
  54.         cout<< "Open file "<< this->confFilePath << " failed!" <<endl;  
  55.         return;  
  56.     }  
  57.       
  58.     string line, name, value;  
  59.     int len=0, start=0;  
  60.           
  61.     while( configFile >> line )  
  62.     {  
  63.         if( line.find('#') != string::npos ) /* annotation */  
  64.             continue;  
  65.         if( line.find("=") == string::npos ) /* not found = */  
  66.             continue;  
  67.         len=line.length();  
  68.         start=line.find("="); /* = 的下标 */  
  69.         name=line.substr(0, start);  
  70.         value=line.substr(start+1, len-(start+1));  
  71.   
  72.         if(name == "db_user") {  
  73.             this->user = value;  
  74.         }  
  75.   
  76.         if(name == "db_user_pwd") {  
  77.             this->password = value;  
  78.         }  
  79.   
  80.         if(name == "db_con_str") {  
  81.             this->conStr = value;  
  82.         }  
  83.   
  84.     }  
  85.   
  86.         cout<< "--------  Read configure file   -------" <<endl;  
  87.     cout<< "file: " << this->confFilePath <<endl;   
  88.         cout<< "db_user: " << user <<endl;  
  89.         cout<< "db_user_pwd: " << password <<endl;  
  90.         cout<< "db_con_str: " << conStr <<endl;  
  91.         cout<< "---------------------------------------" <<endl;  
  92. }  
  93.   
  94. DBwrapper::~DBwrapper()  
  95. {  
  96.       
  97. }  
  98.   
  99. //  
  100. // Desc:  
  101. //   Open connection to Oracle database.  
  102. // Return:  
  103. //   true  -- Successful.  
  104. //   false -- Failed.  
  105. //  
  106. bool DBwrapper::open()  
  107. {  
  108.     try {  
  109.         env = Environment::createEnvironment(Environment::OBJECT);    
  110.         conn = env->createConnection(user, password, conStr);  
  111.         stmt = conn->createStatement();  
  112.     } catch (SQLException ex) {  
  113.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  114.         return false;  
  115.     }  
  116.     return true;  
  117. }  
  118.   
  119. //  
  120. // Desc:  
  121. //   Close connection to Oracle database.  
  122. // Return:  
  123. //   true  -- Successful.  
  124. //   false -- Failed.  
  125. //  
  126. bool DBwrapper::close()  
  127. {  
  128.     try {  
  129.         env->terminateConnection(conn);  
  130.         Environment::terminateEnvironment(env);  
  131.     } catch (SQLException ex) {  
  132.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  133.         return false;  
  134.     }  
  135.     return true;  
  136. }  
  137.   
  138. //  
  139. // Desc:  
  140. //   commit the operation.  
  141. // Return:  
  142. //   true  -- Successful.  
  143. //   false -- Failed.  
  144. //  
  145. bool DBwrapper::commit()  
  146. {  
  147.     try {  
  148.         conn->commit();  
  149.     } catch (SQLException ex) {  
  150.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  151.         return false;  
  152.     }  
  153.     return true;  
  154. }  
  155.   
  156. void DBwrapper::setSQL(string oneSQL)  
  157. {  
  158.     strSQL = oneSQL;  
  159. }  
  160.   
  161. /* generate one SQL string */     
  162. void DBwrapper::generateSQL(map<string, string> oneSQLKV)   
  163. {  
  164.     string oneSQL="";  
  165.     strSQL = oneSQL;  
  166. }  
  167.   
  168. bool DBwrapper::execBatchedUpdate()  
  169. {  
  170.     try {     
  171.         stmt->executeUpdate();  
  172.     } catch (SQLException ex) {  
  173.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  174.         return false;  
  175.     }  
  176.     return true;  
  177. }  
  178.   
  179. bool DBwrapper::execUpdateSQL()  
  180. {  
  181.     try {     
  182.         stmt->setSQL(strSQL);  
  183.         stmt->executeUpdate();  
  184.     } catch (SQLException ex) {  
  185.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  186.         return false;  
  187.     }  
  188.     return true;  
  189. }  
  190.   
  191. bool DBwrapper::execQuerySQL()  
  192. {  
  193.     try {  
  194.         stmt->setSQL(strSQL);  
  195.         rs = stmt->executeQuery();  
  196.     } catch (SQLException ex) {  
  197.         cout<<"Exception: Code - "<<ex.getErrorCode()<<", Message - "<<ex.getMessage();  
  198.         return false;  
  199.     }  
  200.     return true;  
  201. }  
  202.   
  203. ResultSet* DBwrapper::getResultSet()  
  204. {  
  205.     return rs;  
  206. }  
  207.   
  208. Statement* DBwrapper::getStatement()  
  209. {  
  210.     return stmt;  
  211. }  
  212.   
  213. //  
  214. // Desc:  
  215. //   execute SQL string.  
  216. // Parameters:  
  217. //   string sqlStr -- SQL string  
  218. //   string op -- it has only four value.  
  219. //                insert, update, delete, select  
  220. //  
  221. bool DBwrapper::execSQL(string sqlStr, string op)  
  222. {     
  223.     if(!(op == "insert" || op == "update" ||   
  224.        op == "delete" || op == "select")) {  
  225.         cout<<"SQL operation must be in 'insert, update, delete, select'!"<<endl;  
  226.         return false;     
  227.     }  
  228.     strSQL = sqlStr;  
  229.     if(op == "select")   
  230.         return execQuerySQL();  
  231.     else  
  232.         return execUpdateSQL();  
  233. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值