http://www.mscbsc.com/34455/viewspace-27493.html
如果用C/C++开发Oracle数据库后台应用,原来使用Pro*C/C++和OCI比较多,Pro*C/C++的优点是比较简单可以直接用EXEC SQL嵌入SQL语句,有灵活的PL/SQL和动态SQL方法,缺点是需要预编译,比较麻烦,而且使用C++的情况下和C++的OO面向对象特性结合得不好;OCI的效率最高,但接口很复杂,传递的参数中有不少int **之类的东东,学习门槛比较高;Oracle 9i以上版本数据库为C++开发人员推出的OCCI解决了这个问题,它比较完整地实现了OCI的C++面向对象的OO封装,功能也比较强大,效率也很高,下面是一个使用OCCI编程例子:)
使用OCI/OCCI编程操作Oracle数据库,需要运行环境具有oracle的客户端软件。OCI是C语言函数调用。OCCI是C++类调用。下面程序在Linux(RedHat server 5.2)+Oracle10 g下编译运行通过。推荐使用OCCI模式,简洁清晰得多。注意,OCI库函数在Oracle8.1.7前后有很大的变化,当然,是后向兼容的。
// oracle.h头文件
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <assert.h>
#include <occi.h>
#include <occiCommon.h>
#include <occiData.h>
#include <occiObjects.h>
#include <occiAQ.h>
#include <occiControl.h>
using namespace oracle::occi;
class dbAccessor
{
public:
dbAccessor();
~dbAccessor();
int get_dbstat();
bool Connect_DB();
void Disconn_DB();
bool ExecuteUpdate(const char* sql);
ResultSet* ExecuteQuery(const char* sql);
void ClearQuery(ResultSet* set);
void Init(const char* dbName,const char* dbUser,const char* dbPass);
void SetDate(unsigned int paramIndex, time_t timeVal);
private:
Environment* m_env;
Connection* m_conn;
Statement* m_stmt;
const char *m_szUser;
const char *m_szPassword;
const char *m_szDbName;
bool bConnected;
};
bool dbAccessor::Connect_DB()
{
if(m_env ==0)
m_env = Environment::createEnvironment();
if(m_conn==0){
try {
m_conn=m_env->createConnection(m_szUser,m_szPassword,m_szDbName);
} catch (SQLException& ex) {
m_conn = 0;
cout << "connect to database failed: " << ex.getMessage() << endl;
return false;
}
}
return true;
}
void dbAccessor::Disconn_DB()
{
if(m_stmt!=0 && m_conn!=0)
m_conn->terminateStatement(m_stmt);
if(m_conn!=0 && m_env!=0)
m_env->terminateConnection(m_conn);
}
// 执行数据库更新操作,包括insert、update、delete操作
bool dbAccessor::ExecuteUpdate(const char* sql)
{
bool update_OK = true;
if(sql==0){
exit(1);
}
if(m_conn==0&&m_env==0){
exit(1);
}
try {
m_stmt=m_conn->createStatement(sql);
} catch (SQLException& ex) {
m_stmt = NULL;
cout << "ExecuteUpdate failed: " << ex.getMessage() << endl;
exit(1);
}
update_OK = m_stmt->executeUpdate();
return update_OK;
}
//执行数据库查询操作,即select操作
ResultSet* dbAccessor::ExecuteQuery(const char* sql)
{
ResultSet* set=0;
if(sql==0){
exit(1);
}
if(m_conn==0&&m_env==0){
exit(1);
}
try {
m_stmt=m_conn->createStatement(sql);
} catch (SQLException& ex) {
m_stmt = NULL;
cout << "ExecuteQuery failed: " << ex.getMessage() << endl;
exit(1);
}
set=m_stmt->executeQuery();
return set;
}
void dbAccessor::ClearQuery(ResultSet* set)
{
if(m_stmt==0){
exit(1);
}
if(set==0){
exit(1);
}
m_stmt->closeResultSet(set);
}
void dbAccessor::SetDate(unsigned int paramIndex, time_t timeVal)
{
cout<<timeVal<<endl;
m_stmt = m_conn->createStatement();
assert(m_stmt != NULL);
tm* timeStruct = localtime(&timeVal);
Date date(m_env,
timeStruct->tm_year + 1900,
timeStruct->tm_mon + 1,
timeStruct->tm_mday,
timeStruct->tm_hour,
timeStruct->tm_min,
(timeStruct->tm_sec == 60) ? 0 : timeStruct->tm_sec);
m_stmt->setDate(paramIndex, date);
}
// main.cpp文件
#include<string>
#include<string.h>
#include<stdlib.h>
#include<occi.h>
#include<occiCommon.h>
#include<occiData.h>
#include<occiObjects.h>
#include<occiAQ.h>
#include<occiControl.h>
#include "oracle.h"
using namespace std;
using namespace oracle::occi;
int main(void)
{
dbAccessor obj;
obj.Init("192.168.0.1:1521/test","user","pass");
bool conn = obj.Connect_DB();
if(!conn) exit(1);
// 1、插入数据库操作
string sql = "insert into EMAIL0(emailid,checkintime,clientip,clientport,serverip,serverport,capturetime,type,username,password,sendaddress,receiveaddress,subject,ccaddress) ";
sql += "values(1238673850,to_date('04-3-2009','MM-DD-YYYY'),'127.0.0.1',4327,'serverip',110,to_date('04-3-2009','MM-DD-YYYY'),1,'user','pass','sendaddress','receiveaddress','subject','ccaddress')";
obj.ExecuteUpdate(sql.c_str());
// 2、查询数据库操作
sql = "select emailid,to_char(checkintime,'YYYY-MM-DD HH24:MI:SS'),clientip from EMAIL0";
// 第一列emailid:Int型;第二列checkintime:Date类型,转换为字符串类型输出;第三列clientip:string字符串类型
ResultSet* set=obj.ExecuteQuery(sql.c_str());
while(set->next()){
cout << set->getInt(1) << endl; //获取第一列值,int类型
cout << set->getString(2) << endl; //获取第二列值,date类型转换成了字符串类型
cout << set->getString(3) << endl; //获取第三列值,string类型
}
obj.ClearQuery(set);
return 0;
}
//Makefile文件
ICINCHOME=$(ORACLE_HOME)/rdbms/public/
ICLIBHOME=$(ORACLE_HOME)/lib/
ICLIBPATH=-L$(ICLIBHOME)
OCCILIB=$(ICLIBPATH) -locci -lclntsh
OBJS=oracle.o main.o
$(ORACLE_HOME)/lib/libclntsh.so.10.1 /usr/lib/libboost_thread.a
# Linux compiler definitions
CC=g++
CCFLAGS=-g #-fPIC
%.o:%.cpp
$(CC) -c -I$(ICINCHOME) $(CCFLAGS) $<
oracle:${OBJS}
${CC} -g ${CLINK} ${OBJS} ${OCCILIB} -o $@
clean:
@rm -f oracle *.o *~ core.*