您的位置:首页 > 数据库 > Oracle

Oracle occi 绑定变量提高数据插入速度

2012-01-21 09:44 453 查看
转载自: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花多长时间------------------------因为内存溢出了。这个帖子写的很简单,希望是抛砖引玉吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: