转载自:http://fengqing888.blog.163.com/blog/static/3301141620111018017212/
occi是oracle提供的一套对oci封装好的类库,前段时间我抽空看了看相关的文档,本来是想好好的研究研究的,不过因为一直有别的事情要做,所以就没有时间看下去了。论坛上用PRO*C的人多一些。用OCI的好像很少,而且一般问都问些简单的问题,描述的也不太清楚,让人都无从回答。个人觉得OCI的使用率和它作为ORACLE下功能最强的编程接口的地位还是不太符合的。这也许因为它的函数很多而且参数定义非常乱(void ** var)到处都可以看见。不过occi在这方面做了很大的改进,个人觉得还是比较容易上手的,因为它的设计参考了JDBC标准的设计。很多写法基本都是一样的。发这个帖子只是希望有兴趣的人可以一起探讨和学习。
我写了两个简单的小程序,从这两个程序中我们可以看见一些OCCI基本的用法。
环境:win2000pro+sp2
oracle9.0.1
vc6+sp5
a.select 记录
#include "stdio.h"
#include <occi.h>
#include <string>
using namespace oracle:cci;
using namespace std;
int main()
{
try
{
//初始化环境
Environment *env = Environment::createEnvironment(Environment::THREADED_MUTEXED);
//创建连接
Connection *conn = env->createConnection("ems1","ems1","emsdb1";
//创建语句对象
Statement *stmt = conn->createStatement("SELECT * FROM occitest";
ResultSet *rs = stmt->executeQuery();
//rs->setErrorOnNull(3,true);
//逐行读出记录
while(rs->next())
{
printf("The Record is %d,%d,%s.\n",rs->getInt(1),rs->getInt(2),rs->getString(3).c_str());
}
stmt->closeResultSet(rs);
conn->terminateStatement(stmt);
env->terminateConnection(conn);
Environment::terminateEnvironment(env);
}
catch(SQLException &e)
{
printf(e.what());
}
return 0;
}
以我个人的意见来看,这里是OCCI比较方便的地方,以往的oracle的C/C++接口对于动态的语句的支持都是有严格定义(4种动态语句),而其中最复杂的就是列不固定的选择语句,写第4种动态语句是比较复杂的。而OCCI中对这种语句的支持是很容易就可以实现,基本上做到了不需要知道太多的细节。
2.DML操作
#include "stdio.h"
#include <occi.h>
#include <string>
using namespace oracle:cci;
using namespace std;
const int ArraySize=10000;
int main()
{
try
{
printf("Init the Env&Con....\n";
Environment *env = Environment::createEnvironment(Environment::THREADED_MUTEXED);
Connection *conn = env->createConnection("ems1","ems1","emsdb1";
Statement *stmt = conn->createStatement("INSERT INTO occitest VALUES (:fld1,:fld2,:fld3)";
printf("Init ok.\n";
int iFld1[ArraySize],iFld2[ArraySize];
char sFld3[ArraySize][20];
ub2 fld1Len[ArraySize],fld2Len[ArraySize],fld3Len[ArraySize];
for(int i=0;i<ArraySize;i++)
{
iFld1=i+1;
iFld2=i*10+1;
if(i==0)
strcpy(sFld3,"Sky Insert Test!";
else
strcpy(sFld3,"Sky Insert Test1!";
fld1Len=4;
fld2Len=4;
fld3Len=sizeof(sFld3)+1;
}
printf("Begin\n";
stmt->setDataBuffer(1,iFld1,OCCIINT,sizeof(iFld1[0]),fld1Len);
stmt->setDataBuffer(2,iFld2,OCCIINT,sizeof(iFld2[0]),fld2Len);
stmt->setDataBuffer(3,sFld3,OCCI_SQLT_STR,sizeof(sFld3[0]),fld3Len);
stmt->executeArrayUpdate(ArraySize);
printf("End\n";
conn->commit();
conn->terminateStatement(stmt);
env->terminateConnection(conn);
Environment::terminateEnvironment(env);
}
catch(SQLException &e)
{
printf(e.what());
}
return 0;
}
具体的细节就不多说了,我想谈的是一点就是.INSERT语句的格式,很多人在用ADO或者JDBC的时候都很喜欢一个办法就是动态生成一条SQL语句然后在执行,这是个很方便的方法,不过凡事有利就有弊,这个方法的坏处硬编码,如果应用中大量使用就会在SQL语句的解析上花费很多时间,尤其在做批量操作的时候,如果采用这种模式简直就是灾难。所以INSERT 语句写成了"INSERT INTO occitest VALUES (:fld1,:fld2,:fld3)",留下3个占位符。后面是把参数数组传进去,然后一次插入。总的来说我觉得简单的代码还是做了不少事情的。
一次插入10000条记录基本上花了1-2秒就做完了,还是很快的。不过我没有测100000花多长时间------------------------因为内存溢出了。这个帖子写的很简单,希望是抛砖引玉吧。