三、“动态”数据管道的应用前面已将数据管道的应用进行了简单说明,下面将介绍如何在程序中修改和调整数据管道。注意到支撑用户对象中有一个Syntax属性,该属性的数据类型为String,保存用于创建数据管道对象的语法。如果将Syntax输出,将是类似与下面的文本:PIPELINE(source_connect=Book,destination_connect=Desi,type=create,commit=100,errors=100,keyname=person_x)SOURCE(name=person,COLUMN(type=varchar,name=person_no,dbtype=char(8),key=yes,nulls_allowed=no)COLUMN(type=varchar,name=dept_no,dbtype=char(3),nulls_allowed=no)……如果利用字符串函数(比如Mid()、Pos()、Len())对Syntax属性进行操作,应用程序可以动态修改数据管道对象语法,从而实现不同的要求。例如将上面文本中的“type=create”改为“type=update”就改变了数据管道的操作方式。现在我们知道了动态修改数据管道的方法,那么我们能否不建立数据管道对象而只应用支撑用户对象实现管道操作吗?答案是肯定的,方法是通过构造符合Pipeline语法的文本(有关pipeline的语法可以把在画笔中定义的Pipeline对象导成文本文件进行分析),将此文本赋值给Syntax属性,这样不必定义数据管道对象仍然可以进行管道操作。下面是笔者编写的一个从Forpro数据表向Oracle数据库复制数据的函数,由于应用了“动态”数据管道,无需在画笔中创建数据管道对象,从而实现任意表的数据传递。FunctionIntegeruf_foxtoora(transactionatrans_source,transactionatrans_destination,stringas_fox_tablename,stringas_ora_username,stringas_ora_tablename,integerai_pipe_type)其中:atrans_source与源数据库建立连接的事务对象实例atrans_destination与目标数据库建立连接的事务对象实例as_fox_tablenameFoxpro数据表名(不加扩展名.dbf)as_ora_usernameOracle数据库的用户名as_ora_tablenameOracle数据库的表名ai_pipe_type数据管道操作类型返回值:成功返回1,发生错误返回错误代码。脚本如下:inti,li_columncount,li_returnstringls_pipeline1,ls_pipeline2,ls_pipeline3,ls_pipeline4,ls_pipesynstringls_pipetype[5]={create,replace,refresh,append,update}//定义数据管道操作方式stringls_foxtype,ls_oratype,ls_colname,ls_foxdbtype,ls_oradbtype,ls_inital,ls_foxtype1stringls_insertcol,ls_sel,errorspipelinepipe_foxtooradatastorelds_1ls_sel=SELECT*FROM+as_fox_tablenamelds_1=createdatastore//创建动态数据存储对象,用以获取字段名及数据类型lds_1.create(atrans_source.syntaxfromsql(ls_sel,style(type=grid),errors))iflen(errors)0thenreturn-99//若动态数据存储创建失败,返回错误代码-99li_columncount=Integer(lds_1.Object.DataWindow.Column.Count)pipe_foxtoora=createpipelinels_pipeline1=PIPELINE(source_connect=foxtoora,destination_connect=+as_ora_username+,type=+ls_pipetype[ai_pipe_type]+,commit=100,errors=100)ls_pipeline2=SOURCE(name=~+as_fox_tablename+~,ls_pipeline3=RETRIEVE(statement=~PBSELECT(VERSION(400)TABLE(NAME=~~~+as_fox_tablename+~~~)ls_pipeline4=DESTINATION(name=~+as_ora_tablename+~,//循环获取字段名及数据类型,构造动态数据管道语法fori=1toli_columncountls_colname=string(lds_1.describe(#+string(i)+.dbname))ls_foxtype1=string(lds_1.describe(#+string(i)+.coltype))//判断字段数据类型,根据数据类型构造动态数据管道语法CHOOSECASEupper(left(ls_foxtype1,3))CASECHAls_foxtype=charls_foxdbtype=~C+right(ls_foxtype1,len(ls_foxtype1)-pos(ls_foxtype1,()+1)+~ls_oratype=varcharls_oradbtype=~VARCHAR2+right(ls_foxtype1,len(ls_foxtype1)-pos(ls_foxtype1,()+1)+~ls_inital=~spaces~CASEDECls_foxtype=decimalls_foxdbtype=~N+(20,+right(ls_foxtype1,len(ls_foxtype1)-pos(ls_foxtype1,())+~ls_oratype=decimalls_oradbtype=~NUMBER+(20,+right(ls_foxtype1,len(ls_foxtype1)-pos(ls_foxtype1,())+~ls_inital=~0~CASEDATifupper(ls_foxtype1)=DATEthenls_foxtype=datels_foxdbtype=~D~elseifupper(ls_foxtype1)=DATETIMEthenls_foxtype=datetimels_foxdbtype=~T~endifls_oratype=datetimels_oradbtype=~DATE~ls_inital=~today~CASEINTls_foxtype=decimalls_foxdbtype=~N(8,0)~ls_oratype=decimalls_oradbtype=~NUMBER(8,0)~ls_inital=~0~CASELONls_foxtype=longls_foxdbtype=~I~ls_oratype=doublels_oradbtype=~FLOAT~ls_inital=~0~CASEDOUls_foxtype=decimalls_foxdbtype=~T~ls_oratype=decimalls_oradbtype=~NUMBER(20,8)~ls_inital=~0~CASEBITls_foxtype=bitls_foxdbtype=~T~ls_oratype=doublels_oradbtype=~FLOAT~ls_inital=~0~CASENUMls_foxtype=doublels_foxdbtype=~B~ls_oratype=doublels_oradbtype=~FLOAT~ls_inital=~0~ENDCHOOSEls_pipeline2+=COLUMN(type=+ls_foxtype+,name=~+ls_colname+~,dbtype=+ls_foxdbtype+,nulls_allowed=no)+~r~nls_pipeline3+=COLUMN(NAME=~~~+as_fox_tablename+.+ls_colname+~~~)ls_pipeline4+=COLUMN(type=+ls_oratype+,name=~+ls_colname+~,dbtype=+ls_oradbtype+,nulls_allowed=no,initial_value=+ls_inital+)+~r~nnextls_pipeline2+=+)ls_pipeline3+=)~)ls_pipeline4+=+)ls_pipesyn=ls_pipeline1+~r~n+ls_pipeline2+~r~n+ls_pipeline3+~r~n+ls_pipeline4messagebox(,ls_pipesyn)pipe_foxtoora.syntax=ls_pipesyn//将数据管道语法字符串赋值给Syntax属性li_return=pipe_foxtoora.start(atrans_source,atrans_destination,lds_1)//启动数据管道destroylds_1destroypipe_foxtoorareturnli_return//返回数据管道执行成功标志或错误代码四、结论在移动计算日益普及的今天,各种数据相互传递已经成为应用程序的普遍要求。数据管道技术提供了在数据库内部、数据库之间,甚至不同的数据库管理系统之间快速复制数据的简便途径。而使用“动态”数据管道可以使程序具有较强的适应性,操作更加灵活,进而能够满足数据移动中的特殊要求。