|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你可以配置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[20];//用户名
charPwd[20];//暗码
charDB[20];//数据库服务名
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[256];
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[i]=(short*)malloc(sizeof(short*));
BindUnit->V[i]=(char*)malloc(MAX_VNAME_LEN);
}
for(inti=0;i<MAX_ITEMS;i++)
{
SelectUnit->I[i]=(short*)malloc(sizeof(short*));
SelectUnit->V[i]=(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[i]),&(SelectUnit->T[i]),&null_ok);
switch(SelectUnit->T[i])
{
case1://CHAR
break;
case2://NUMBER
sqlprc(&(SelectUnit->L[i]),&precision,&scale);
if(precision==0)
precision=40;
SelectUnit->L[i]=precision+2;
break;
case8://LONG
SelectUnit->L[i]=240;
break;
case11://ROWID
SelectUnit->L[i]=18;
break;
case12://DATE
SelectUnit->L[i]=9;
break;
case23://RAW
break;
case24://LONGRAW
SelectUnit->L[i]=240;
break;
}
SelectUnit->V[i]=(char*)realloc(SelectUnit->V[i],SelectUnit->L[i]+1);
SelectUnit->T[i]=1;//把一切范例转换为字符型
}
EXECSQLWHENEVERNOTFOUNDgotoEndFor;
for(;;)
{
EXECSQLFETCHCursorbaseUSINGDESCRIPTORSelectUnit;
//输入各字段
for(inti=0;i<SelectUnit->F;i++)
{
charbuffer[256];
if(i!=SelectUnit->F-1)
sprintf(buffer,"%s",SelectUnit->V[i]);
elsesprintf(buffer,"%s
",SelectUnit->V[i]);
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[i]!=(char*)NULL)
free(SelectUnit->V[i]);
free(SelectUnit->I[i]);
}
for(intj=0;j<MAX_ITEMS;j++)
{
if(BindUnit->V[j]!=(char*)NULL)
free(BindUnit->V[j]);
free(BindUnit->I[j]);
}
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[256];
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[i],iStart,*(int*)LengthArray->Items[i]+iStart-1);
iStart+=*(int*)LengthArray->Items[i];
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的被广泛接受。 |
|