在程序中执行管道

应用程序中,用户经常需要能够将其他格式的数据灌入到数据库中,这或者是由不能上

网但还有录入数据工作的职员提供的,或者是原来其他软件系统提交的数据。总之,在

应用程序中应该提供将数据从不同的数据库拷贝到当前数据库中的手段。在应用程序中

使用管道可以很好地解决这些实际应用。 
应用程序中使用管道,不像在数据管道画板中那样简单,需要以下步骤: 
a.创建相关对象; 
b.和源目标数据库建立联接; 
c.创建数据管道,并设置其相关属性; 
d.执行管道,并处理各种异常。 
在脚本中使用数据管道,需要创建三个对象:数据管道对象、数据管道用户对象以及一

个保存错误信息的数据窗口对象,其中数据窗口对象是在管道运行错误时由系统自动创

建的。 
数据管道对象在数据管道画板中创建,数据管道用户对象在Standard Class用户对象中

创建,这些对象的创建方法在前面都做过了详细的介绍。接下来是在程序中如何创建这

些对象。 
和datastore对象类似,管道用户对象是不可见的,也必须首先用脚本创建才能使用。为

了能够在窗口的不同事件中都操作管道对象,首先声明如下实例变量: 
Transaction itrans_dest,itrans_src//定义两个事务对象,分别用来联接源和目标数

据库 
u_pipeline iuo_p// 定义一个管道用户对象类型的变量。u_pipeline是已经定 
// 义好的管道用户对象 
然后,在窗口的Open事件中进行初始化工作。编写如下脚本: 
SetPointer(HourGlass!) 

iuo_p = Create u_pipeline  //u_pipeline为在标准类中创建的管道用户对象名称 
itrans_dest = Create Transaction 
itrans_src = Create Transaction 

itrans_dest.DBMS = ProfileString("MY.INI","Destination","DBMS"," ") 
itrans_dest.Dest = ProfileString("MY.INI","Destination", "database"," ") 
itrans_dest.LogID = ProfileString("MY.INI","Destination","LogID"," ") 
itrans_dest.LogPass = ProfileString("MY.INI","Destination","LogPassword"," ") 
itrans_dest.ServerName = ProfileString("MY.INI","Destination","ServerName"," 

") 
itrans_dest.UserID = ProfileString("MY.INI","Destination","UserID"," ") 
itrans_dest.DBPass = ProfileString("MY.INI","Destination","DestPassword", " 

") 
itrans_dest.Lock = ProfileString("MY.INI","Destination","Lock"," ") 
itrans_dest.DbParm = ProfileString("MY.INI","Destination","DbParm"," ") 

Connect Using itrans_dest; 
If itrans_dest.SQLcode <> 0 Then 
cb_1.Enabled = False 
Beep(1) 
MessageBox("错误","不能目标数据库建立联接!",Exclamation!) 
End If 
itrans_src.DBMS = ProfileString("MY.INI","Source","DBMS"," ") 
itrans_src.Source = ProfileString("MY.INI","Source","database"," ") 
itrans_src.LogID = ProfileString("MY.INI","Source","LogID"," ") 
itrans_src.LogPass = ProfileString("MY.INI","Source","LogPassword"," ") 
itrans_src.ServerName = ProfileString("MY.INI","Source","ServerName"," ") 
itrans_src.UserID = ProfileString("MY.INI","Source","UserID"," ") 
itrans_src.DBPass = ProfileString("MY.INI","Source","SourcePassword", " ") 
itrans_src.Lock = ProfileString("MY.INI","Source","Lock"," ") 
itrans_src.DbParm = ProfileString("MY.INI","Source","DbParm"," ") 

Connect Using itrans_src; 
If itrans_src.SQLcode <> 0 Then 
cb_1.Enabled = False 
Beep(1) 
MessageBox("错误","不能源数据库建立联接!",Exclamation!) 
End If 

iuo_p.dataobject = "p_address"//p_address为在数据管道画板中定义的数据管道对象 
iuo_p.uf_set(st_1)//调用用户管道对象函数进行初始化 
上面的脚本也可以放在用户定制事件中,然后在窗口的Open事件中使用函数PostEvent来

触发该事件,以便加快窗口的打开速度。 
当管道执行时,应该将管道执行的进度情况告诉用户。所以,在管道用户对象的相关事

件中编写脚本。为了显示进度信息,在窗口的Open事件中调用了uf_set函数,并将静态

文本st_1作为参数,以便管道用户对象知道将进度信息显示在什么控件上。需要在至少

三个事件中显示管道的执行进度,所以静态文本参数在管道用户对象中应该保存在一个

实例变量中,而该实例变量在窗口中不应该直接引用,所以管道用户对象对外提供了一

个自定义函数,使用该函数进行初始化。首先定义一个实例变量: 
statictext ist_1 
然后,在uf_set函数中对该实例变量进行初始化: 

/////////////////////////////////////////////////////////////////////////////

///////////////// 
//函数名称:uf_set 
//参数:statictext类型的ist_1 
//返回值:没有 
//函数功能:对管道用户对象的实例变量ist_1进行初始化 
/////////////////////////////////////////////////////////////////////////////

///////////////// 
ist_1= ist_1 
然后,在管道用户对象的PipeStart事件中编写如下脚本: 
ist_1.Text = "开始执行数据管道......" 
在管道用户对象的PipeMeter事件中编写如下脚本: 
ist_1.Text = "已经读取:" + String(This.rowsread) + & 
"错误数据:" + String(This.rowsinerror) + & 
"已经写入:" + String(This.rowswritten) 
在管道用户对象的PipeEnd事件中编写如下脚本: 
ist_1.Text = "开始执行数据管道......" 
至此,信息显示的脚本就编写完了。当然,还可以在管道用户对象中完成更多的工作,

这样可以增强管道的可重用性。比如,将和源目标库联结的脚本放到管道用户对象的某

个自定义函数中,在窗口中调用即可;还可以将设置管道DataObject属性的语句放到管

道用户对象的某个函数中,并根据窗口中调用该函数时的参数来设置该属性,这样可以

使管道用户对象有更好的通用性。因为关于用户对象还没有介绍,所以本节没有按照更

通用的思想介绍编程。 
剩下的工作就是提供让用户开始执行管道的命令按钮。可以在“执行管道”命令按钮的

Clicked事件中编写如下脚本: 
String ls_msg 

ls_msg = wf_RunPipe() 
If ls_msg <> "ok" Then 
Beep(1) 
MessageBox("错误",ls_msg) 
End If 
窗口函数wf_RunPipe用来运行管道,并且返回管道的执行情况。函数的定义如下: 
///////////////////////////////////////////////// 
//函数名称:wf_RunPipe 
//参数:无 
//返回值:String类型的Start函数的执行反馈信息 
//函数功能:开始执行管道,并根据管道执 
//行函数的返回值返回相应的汉字信息 
///////////////////////////////////////////////// 
String ls_Return = "ok" 

Choose Case iuo_p.start(itrans_src,itrans_dest,dw_1) 
Case -1 
ls_Return="管道打开失败" 
Case -2 
ls_Return="列太多" 
Case -3 
ls_Return="表已经存在" 
Case -4 
ls_Return="表不存在" 
Case -5 
ls_Return="联结错误" 
Case -6 
ls_Return="错误的检索变量" 
Case -7 
ls_Return="列不匹配" 
Case -8 
ls_Return="源中有致命的SQL错误" 
Case -9 
ls_Return="目标中有致命的SQL错误" 
Case -10 
ls_Return="超出了最大的错误数" 
Case -12 
ls_Return="表语法错误" 
Case -13 
ls_Return="没有提供必须的主键" 
Case -15 
ls_Return="管道操作已经进行" 
Case -16 
ls_Return="源数据库中有错误" 
Case -17 
ls_Return="目标数据库中有错误" 
Case -18 
ls_Return="目标数据库是只读的" 
End Choose 
Return ls_Return 
在按钮“取消”的Clicked事件中可以随时让用户取消管道的执行。可以编写如下脚本: 
If iuo_p.Cancel() < 0 Then 
Beep(1) 
MessageBox("取消","取消失败! ",Exclamaition!) 
End If 
在按钮“修改”的Clicked事件中提供当管道执行失败后的修正功能,可以编写如下脚本

: 
String ls_msg 

ls_msg = wf_RepairPipe() 
If ls_msg <> "ok" Then 
Beep(1) 
MessageBox("错误",ls_msg) 
End If 
其中,窗口函数wf_RepairPipe和上面的wf_RunPipe类似,只是调用函数iu_p.Repair

(it_dest),然后根据该函数的返回值决定返回什么样的汉字信息。 
当窗口关闭时,还应该做清除工作,将一些实例变量占用的内存释放。在窗口的Close事

件中编写如下脚本: 
destroy it_dest 
destroy it_src 
destroy iu_p 

通过本章的介绍,想必已经清楚了管道的强大功能,知道了这是解决实际应用中一个重

要问题的得力工具,并且也掌握了在脚本中如何使用该对象。但是,在实际应用中真正

用好该对象,如果不编写通用的管道调用脚本,该对象的使用还有很多的局限性。比如

,只能限制固定表结构的灌入,或者只能在特定的数据库之间使用管道等等。为此,本

章也提到过解决方法,但没有提供具体实例。比如,将源表和目标表的profile配置放置

到文件中,并给用户提供配置界面,以便用户方便地修改配置文件来指定在任意数据库

之间拷贝数据或结构;还可以提供界面让用户来指定数据管道要使用哪个(或者哪些)

源表、源表中的哪些字段,灌入到哪个目标表中,这些可以通过修改数据管道的语法来

实现,从而构造出用户可以像在数据管道画板中那样灵活设定数据管道定义的功能,来

实现更为通用、更能够解决实际应用问题的管道功能。 
 

转载 www.study01job.com  郭宝利