C++通过occi连接和操作oracle(原创)

最近某程序需要迁移到另一个系统中运行,后台数据库由mysql改为oracle,在网上零碎查找了些资料,总算成功完成任务。
记录下一点点心得,希望能帮到需要的朋友。
 
1. oracle 环境配置
先下载下面两个包(这里是64位,视实际情况而定)
            instantclient-basic-linux.x64-11.2.0.3.0.zip 和 instantclient-sdk-linux.x64-11.2.0.3.0.zip (oracle官方网站,注册后才能下载)
            两个zip包在同一目录下解压,文件会放在instantclient_11_2中,再将此目录放到oracle期望的安装目录下,比如 /home/oracle
cd /home/oracle,然后建立链接
            ln -s  instantclient_11_2/sdk/include/ include
            ln -s instantclient_11_2/ lib64
            进入 instantclient_11_2 ,再建立链接:
            ln -s libclntsh.so.11.1 libclntsh.so
            ln -s libocci.so.11.1 libocci.so
vim /etc/ld.so.conf,添加一行/home/oracle/lib64,再执行/sbin/ldconfig  (需要root)
          然后可以用命令/sbin/ldconfig -p|grep oci 来查看一下。
 
2. 编译选项
g++ -I/home/oracle/lib64/sdk/include -L/home/oracle/lib64 xxxxx.cpp -locci -lclntsh -o your_program_name (注意目录与上面安装目录相对应)
 
如果是采用automake来生成Makefile,需要先修改Makefile.am,增加以下几项:
INCLUDES=-I/home/oracle/lib64/sdk/include
AM_LDFLAGS=-L/home/oracle/lib64
xxxx_LIBADD = -locci -lclntsh (xxxx表示Makefile.am中的lib_PROGRAMS或者lib_LTLIBRARIES)
然后再执行./configure和automake
 
3.程序调用
3.1    头文件:
#include <occi.h>
using namespace oracle::occi;

  

3.2    初始化及连接:
Environment *env;
Connection *conn;
Statement *stmt;
 
try {
    env = Environment::createEnvironment ("UTF8", "UTF8");    // 编码可能需要注意一下,视实际而定
    if(env == NULL)
        return false;
 
    string conn_db = "//" + host + "/" + db_name;                                                                                                   
    conn = env->createConnection(user, passwd, conn_db);   // 第3个参数的格式为: "//IP:port/dbname"     
    stmt = conn->createStatement();
} catch (SQLException ex) {  // 相关的操作都建议用try包起来,可以用下面的方式看错误码和描述,方便调试,下面的就省略不写了。
    log_error    ("connect oracle error, err_code: %d; err_msg: %s\n", ex.getErrorCode(), ex.getMessage().c_str()); //log_error是自己写的打印日志的函数
    return false;
}

 

3.3    select通过executeQuery来完成:

stmt->setSQL(sql);
ResultSet *rset = stmt->executeQuery();
然后可以调用rset->getString(int column),getInt等方法取得相应字段,详见http://docs.oracle.com/cd/B10500_01/appdev.920/a96583/cci08r18.htm#1076230
    对于Clob类型的字段的读写特殊一些,可见http://docs.oracle.com/cd/B10500_01/appdev.920/a96583/cciaadem.htm 中的dumpClob及populateClob两个函数,如果clob中有中文,还要在clob.open后设置下编码,如clob.setCharSetForm(OCCI_SQLCS_IMPLICIT);clob.setCharSetId("UTF8");
    Date类型需要转换一下,读取为字符串可以用: rset->getDate(2).toText("YYYY-MM-DD HH24:MI:SS").c_str()
 
3.4    update和insert都是通过executeUpdate来完成:
stmt->setSQL(sql);
stmt->executeUpdate();
conn->commit();
 
3.5    使用完后关闭

 

stmt->closeResultSet(rset);
conn->terminateStatement(stmt);
env->terminateConnection (conn);
Environment::terminateEnvironment (env);

  

 
另:
对于习惯于mysql的朋友,如果不熟悉oracle的话,写sql语句时可能会遇到些问题,下面是我碰到的几个:
a)    sql语句中column的名称不能有引号、反引号等,直接写即可。
b)    oracle在insert时,需要在sql中写明主键的值,不允许为空,好在可以通过建立一个sequence来实现主键自增,这样就可以不写明主键。
c)    sql语句中直接写表名即可,而不是dbname.tablename的写法。
 
posted @ 2012-09-15 16:39  thomaslee  阅读(856)  评论(0编辑  收藏  举报