乐观 发表于 2015-1-16 22:38:38

MYSQL网页设计PROC++批量导进导出ORACLE数据库表

你可以配置MySQL运行在微小的嵌入式应用程序中,处理的数据可能不足1Mb??而你也可以用它来处理数Tb的数据。MySQL获得这种可扩展性的路径之一是通过一个人们所熟知的存储过程,这是一个运行在程序之外的微型、预编译程序。oracle|数据|数据库
比来在开辟一个项目中,为懂得决数据库IO瓶颈,不能不把数据库中的数据导出为文本文件。文本传到客户端后又要导进到数据库。自己用C++Builder嵌进PROC++写了一个导进导出的DLL。假如对你有效深感侥幸!具体内容以下:



1、筹办事情

盘算机情况:Win2000PRO,ORACLE9i,C++Builder5.5

引进需要的ORACLE外部函数:要用的函数在$(ORACEL_HOME)inqlora9.dll链接库中。为了能在C++Builder中利用,先得天生LIB:implibsqlora9.libsqlora9.dll



2、源文件剖析

//-------------------------------------------------------------------------

//到场需要的头文件

#include<vcl.h>#include<windows.h>#include<stdio.h>#include<stdlib.h>#include<string.h>

#include<time.h>#include<math.h>#include<fcntl.h>#include<io.h>#include<systat.h>

//申明DLL的输入函数

extern"C"_declspec(dllexport)int_stdcallConnectDB(constchar*Username,

constchar*Password,constchar*Dbname);

extern"C"_declspec(dllexport)int_stdcallImportTxtfile(TList*LengthArray,

String*FieldArray,constchar*TableName,

constchar*FileName);

extern"C"_declspec(dllexport)int_stdcallExportTxtfile(constchar*Sql,

constchar*FileName);

#pragmahdrstop

//----------------------------------------------------------------------------

#defineMAX_ITEMS20//界说最年夜字段数

#defineMAX_VNAME_LEN30//界说选择表项最年夜长度

#defineMAX_INAME_LEN30//界说唆使器变量名字的最年夜长度



EXECSQLINCLUDEsqlca;//申明SQL通信区

EXECSQLINCLUDEoraca;//申明ORACLE通信区

EXECSQLINCLUDEsqlda;//申明SQL语句形貌布局/*SQLDA布局体请查相干材料*/



EXECORACLEOPTION(ORACA=YES);

EXECORACLEOPTION(RELEASE_CURSOR=YES);



//申明ORACLE内部函数

extern"C"_declspec(dllimport)void_stdcallsqlclu(SQLDA*);

extern"C"_declspec(dllimport)void_stdcallsqlnul(short*,short*,int*);

extern"C"_declspec(dllimport)void_stdcallsqlprc(int*,int*,int*);

extern"C"_declspec(dllimport)structSQLDA*_stdcallsqlald(int,unsignedint,unsignedint);



SQLDA*SelectUnit;//界说选择项形貌

SQLDA*BindUnit;//界说输出项空间

//界说变量,以寄存毗连数据库的参数

EXECSQLBEGINDECLARESECTION;

charUser;//用户名

charPwd;//暗码

charDB;//数据库服务名

EXECSQLENDDECLARESECTION;



boolbConnect=false;//是不是毗连标记

#pragmahdrstop



#pragmaargsused

//C++BuilderDLL的主函数

BOOLWINAPIDllMain(HINSTANCEhinstDLL,DWORDfwdreason,LPVOIDlpvReserved)

{

return1;

}



/*---------------------------------------------------------------------------

毗连数据库

---------------------------------------------------------------------------*/

int_stdcallConnectDB(constchar*Username,constchar*Password,

constchar*Dbname)

{

strcpy(User,Username);

strcpy(Pwd,Password);

strcpy(DB,Dbname);



EXECSQLCONNECT:UserIDENTIFIEDBY:PwdUSING:DB;



if(sqlca.sqlcode<0)

return-1;



bConnect=true;

return0;

}

/*---------------------------------------------------------------------------

导出文本函数

由于不断定SELECT语句的表及字段,以是我利用静态语句(ORACLEDYNAMICSQL)的//第四种体例。静态SQL办法四是在不断定SQL语句的选择项与输出项,且不知个数与数据范例的情形下利用的一种庞大程序计划手艺。

---------------------------------------------------------------------------*/

int_stdcallExportTxtfile(constchar*Sql/*SQL选择语句*/,constcharFileName/*导出方针文本文件名*/)

{

intnull_ok,precision,scale;



inthandle;



if((handle=open(FileName,O_CREAT|O_TEXT|O_APPEND|O_RDWR,S_IREAD|S_IWRITE))==-1)

{

//文件翻开堕落

return-1;

}

//界说变量,以寄存SQL语句

EXECSQLBEGINDECLARESECTION;

charsqlstr;

EXECSQLENDDECLARESECTION;



//反省是不是毗连数据库

if(bConnect==false)return-2;



strcpy(sqlstr/*.arr*/,Sql);

//sqlstr.len=strlen(sql);



//给形貌辨别配空间

if((SelectUnit=sqlald(MAX_ITEMS,MAX_VNAME_LEN,MAX_INAME_LEN))==(SQLDA*)NULL)

{

//空间分派失利

return-3;

}



if((BindUnit=sqlald(MAX_ITEMS,MAX_VNAME_LEN,MAX_INAME_LEN))==(SQLDA*)NULL)

{

//空间分派失利

return-3;

}

//给查询前往值存储辨别配空间

SelectUnit->N=MAX_ITEMS;

for(inti=0;i<MAX_ITEMS;i++)

{

BindUnit->I=(short*)malloc(sizeof(short*));

BindUnit->V=(char*)malloc(MAX_VNAME_LEN);

}

for(inti=0;i<MAX_ITEMS;i++)

{

SelectUnit->I=(short*)malloc(sizeof(short*));

SelectUnit->V=(char*)malloc(MAX_VNAME_LEN);

}



EXECSQLWHENEVERSQLERRORGOTOsqlerr;//DOsql_error("导出堕落");

//设置SQL语句

EXECSQLPREPARESQLSAFROM:sqlstr;

EXECSQLDECLARECursorbaseCURSORFORSQLSA;



//输出形貌处置

BindUnit->N=MAX_ITEMS;

EXECSQLDESCRIBEBINDVARIABLESforSQLSAINTOBindUnit;



if(BindUnit->F<0)

{

return-4;

//输出项过量

}

BindUnit->N=BindUnit->F;

//翻开光标

EXECSQLOPENCursorbaseUSINGDESCRIPTORBindUnit;



//选择项处置

EXECSQLDESCRIBESELECTLISTforSQLSAINTOSelectUnit;



if(SelectUnit->F<0)

{

return-4;

//选择表项过量

}

SelectUnit->N=SelectUnit->F;

//由于一切格局,范例都是不断定的,以是要失掉准确的前往值就要处置格局

for(inti=0;i<SelectUnit->F;i++)

{

sqlnul(&(SelectUnit->T),&(SelectUnit->T),&null_ok);

switch(SelectUnit->T)

{

case1://CHAR

break;

case2://NUMBER

sqlprc(&(SelectUnit->L),&precision,&scale);

if(precision==0)

precision=40;

SelectUnit->L=precision+2;

break;

case8://LONG

SelectUnit->L=240;

break;

case11://ROWID

SelectUnit->L=18;

break;

case12://DATE

SelectUnit->L=9;

break;

case23://RAW

break;

case24://LONGRAW

SelectUnit->L=240;

break;

}



SelectUnit->V=(char*)realloc(SelectUnit->V,SelectUnit->L+1);



SelectUnit->T=1;//把一切范例转换为字符型

}



EXECSQLWHENEVERNOTFOUNDgotoEndFor;



for(;;)

{

EXECSQLFETCHCursorbaseUSINGDESCRIPTORSelectUnit;



//输入各字段

for(inti=0;i<SelectUnit->F;i++)

{

charbuffer;



if(i!=SelectUnit->F-1)

sprintf(buffer,"%s",SelectUnit->V);

elsesprintf(buffer,"%s
",SelectUnit->V);



intlength=strlen(buffer);



if(write(handle,buffer,length)!=length)

{

return-5;

//写文件失利exit(1);

}

}



}



EndFor:



close(handle);



for(inti=0;i<MAX_ITEMS;i++)

{

if(SelectUnit->V!=(char*)NULL)

free(SelectUnit->V);



free(SelectUnit->I);

}



for(intj=0;j<MAX_ITEMS;j++)

{

if(BindUnit->V!=(char*)NULL)

free(BindUnit->V);



free(BindUnit->I);

}



sqlclu(SelectUnit);

sqlclu(BindUnit);



EXECSQLCLOSECursorbase;



return0;



sqlerr:

return-6;

}



/*----------------------------------------------------------------------------

导进文本

为了批量导进,在此我挪用的sqlldr工具

起首天生SQL*Loader把持文件,后运转sqlldr

----------------------------------------------------------------------------*/

int_stdcallImportTxtfile(TListLengthArray/*导进文本的字段长度链表*/,

String*FieldArray/*数据库表的了段名数组*/,constcharTableName/*导进的方针表*/,constcharFileName/*导进的源文本文件*/)

{

//发生SQL*Loader把持文件

FILE*fout,*fp;

charExecommand;



charsqlload[]=".qlload.ctl";



//反省是不是毗连数据库

if(bConnect==false)return-2;



if((fout=fopen(sqlload,"w"))==NULL)

{

//创建把持文件堕落

return-1;

}



fprintf(fout,"LOADDATA
");

fprintf(fout,"INFILE%s
",FileName);

fprintf(fout,"APPENDINTOTABLE%s(
",TableName);



intiStart=1;

for(inti=0;i<LengthArray->Count;i++)

{

fprintf(fout,"%11sPOSITION(%d:%d)",FieldArray,iStart,*(int*)LengthArray->Items+iStart-1);

iStart+=*(int*)LengthArray->Items;

fprintf(fout,"CHAR");



if(i<LengthArray->Count-1)

fprintf(fout,",
");

}

fprintf(fout,")
");

fclose(fout);



sprintf(Execommand,"sqlldr.exeuserid=%s/%s@%scontrol=%s",

User,Pwd,DB,sqlload);



if(system(Execommand)==-1)

{

//SQL*Loader实行毛病

return-1;

}



return0;

}





//----------------------------------------------------------------------------

3、编译

用ORACLE的PROC预编译器预编后,放进C++Builder中联编。联编时需到场后面天生的sqlora9.lib。联编时还要注重,一切PROC天生的ORACLE外部函数挪用都要申明为extern"C"_declspec(dllexport)TYPE_stdcall范例。



程度无限还请包涵!!!请多多指导。QQ:5005647


每个人都在使用它。MySQL是开源LAMP组合的一个标准组件:Linux、Apache、MySQL和Perl/PHP。根据Evans的调查,LAMP组合的迅速推广很大程度上代表着MySQL的被广泛接受。

若天明 发表于 2015-1-19 20:14:41

财务软件要用SQL也只是后台的数据库而已,软件都是成品的,当然多学东西肯定是有好处的..

莫相离 发表于 2015-1-26 22:51:15

连做梦都在想页面结构是怎么样的,绝非虚言

谁可相欹 发表于 2015-2-4 21:28:35

你可以简单地认为适合的就是好,不适合就是不好。

山那边是海 发表于 2015-2-10 14:36:40

SQLServer的异构移植功能个人感觉最好了。(如果对比过SQLServer的链接服务器和Oracle的透明网关的朋友会发现SQLServer的sp_addlinkedserver(openquery)异构数据库系列比Oracle真是强太多了。)

再现理想 发表于 2015-3-1 12:09:30

还不是性能有问题!否则面向对象的数据库早就实现了!建议使用CLR的地方一般是和应用的复杂程度或操作系统环境有很高的耦合度的场景。如你想构建复杂的算法,并且用到了大量的指针和高级数据模型。

活着的死人 发表于 2015-3-10 16:53:35

其实可以做一下类比,Oracle等数据库产品老早就支持了java编程,而且提供了java池参数作为用户配置接口。但是现在有哪些系统大批使用了java存储过程?!连Oracle自己的应用都不用为什么?!

小魔女 发表于 2015-3-17 09:09:10

原理很简单,对要求长时间计算某一时间点的报表生成和防用户操作错误很有帮助。但是比起Oracle10g的闪回技术还是细粒度不够。可惜!

金色的骷髅 发表于 2015-3-24 04:58:40

SQLServer的异构移植功能个人感觉最好了。(如果对比过SQLServer的链接服务器和Oracle的透明网关的朋友会发现SQLServer的sp_addlinkedserver(openquery)异构数据库系列比Oracle真是强太多了。)
页: [1]
查看完整版本: MYSQL网页设计PROC++批量导进导出ORACLE数据库表