使用数据管道实现数据的自动迁移和备份
摘要:针对MIS系统的开发和使用过程中数据的备份和迁移问题,提出了解决问题的基本思路和方案,详细阐述了方案实施过程中涉及的方法和技巧,并对使用PowerBuild开发MIS系统的一般思路作了简要的介绍和说明。
关键词:MIS;PowerBuild;数据管道;数据迁移;数据备份
分类号:TP311.52
1.引言
在MIS系统的开发中,PowerBuild7.0以其强大的数据处理能力、丰富的数据库接口和数据访问能力、支持三层或多层应用结构的开发和对Internet的有力支持,成为目前领先的Client/Server开发工具。
在MIS系统的开发和使用过程中,常常需要对数据进行备份和迁移。当应用系统开发成功后,系统从开发环境向运行环境迁移时,当旧的系统需要升级时,当新系统为了兼容原有系统使用时,当自动进行数据的备份和恢复时,或者为了提取数据样本时,开发者或用户可以通过手工的方法完成操作,但某些情况下, 开发者应该考虑在应用程序中实现数据的自动迁移。PowerBuild的数据管道是实现这种自动移动的有效方法之一。
在PowerBuild中,数据管道可以实现数据表间数据的移动,它可以将数据从一个或多个源表(也可以是存储过程)中输送到一个新的或现有的目标表中,这些数据表可以在同一个数据库中,也可以在不同的数据库中,甚至可以在不同的数据库管理系统(DBMS)中。
2.实现方法
通过应用程序实现数据的自动迁移,要求被操作的源和目标数据库已经存在,并且数据迁移的策略(数据管道)也应建立。在此基础上,通过应用程序使用数据管道,实现数据的自动迁移。
2.1实现步骤
一般说来,在应用程序中使用数据管道有五个基本步骤:
(1)创建对象 创建数据管道对象、管道对象的支撑用户对象和一个窗口对象。
(2)初始化操作 创建两个事务对象的实例,分别连接源和目的数据库;创建管道对象的支撑用户对象的一个实例,并初始化为已经建立的数据管道对象。
(3)启动数据管道 通过支撑用户对象的实例启动数据管道
(4)处理错误 对管道操作中出错的数据行可以进行修复和放弃。
(5)结束操作 断开数据库的连接,并释放用过的实例,关闭窗口。
2.2创建对象
2.2.1创建数据管道对象
使用数据管道实现数据的迁移,不管是在PowerBuild环境中以交互方式进行还是使用应用程序进行,首先必须建立数据管道。
建立数据管道应该在PowerBuild环境中进行。
1) 配置两个ODBC数据源,这里假设它们是S和D,其中,S连接源数据库,D连接目标数据库。
2) 通过“New→Database→Pipeline”定义管道对象。在定义过程中,数据源如果是数据表,则“Data Source”选“Quick Select”/“SQL Select”,如果是存储过程,则选“Stored Procedure”;“Source Connection”选S,“Destination Connection”选D;选定源连接中的数据表,根据需要选定字段,并设置数据行的筛选条件;设定目标表的名称,管道操作的类型;存盘。
管道操作的类型有创建、替换、刷新、增加或修改几种,根据需要选择其中一种。正常情况下,如果进行数据备份,应定义两个相关的管道对象,这两个 管道对象只有管道操作的类型不同,其中一个的操作类型为“创建”,另外一个为“增加或修改”。当目标数据库中无相应数据表(第一次备份)时,使用“创建” 操作的管道对象;当目标数据库中有相应数据表(不是第一次备份)时,使用“增加或修改”操作的管道对象。在这里,定义两个管道对象为 Pile_Create和Pile_Modify。
2.2.2创建管道的支撑用户对象
创建的两个管道对象Pile_Create和Pile_Modify可以实现交互方式的数据迁移,但还不能在应用程序中使用。为了在应用程序中使用管道对象的属性和函数,应该建立管道对象的支撑用户对象。
为了提高程序的通用性,可以设置一个比较通用的管道对象的用户对象(即不用指定数据对象)。
通过选择“New→Object→Standard Class”,再选择“Pipeline”,建立管道用户对象,其名字设定为uo_pipeline。用户对象uo_pipeline具有6个属性,5个事件,9个函数,其中在应用程序中较常使用的属性、事件、函数如表1、表2、表3所示。
表1 管道对象的属性
属性名 |
数据类型 |
含义 |
RowsInError |
Long |
指明管道运行期间出错行的行数 |
RowsRead |
Long |
指明管道读入的行数 |
RowsWritten |
Long |
指明管道写出的行数 |
DataObject |
String |
指明管道对象的名称(如Pile_Create) |
表2 管道对象的事件
事件 |
触发时机 |
PipeEnd |
当Start()或Repair()函数执行结束时出发 |
PipeMeter |
每读入或写出一块数据后触发。数据块大小由Commit因子决定 |
PipeStart |
当Start()或Repair()函数开始执行时触发 |
表3 管道对象的函数
函数 |
返回值数据类型 |
功能 |
Cancel |
Integer |
终止管道运行 |
Repair |
Integer |
修正管道用户对象的错误数据窗口,用正确的数据更新目标数据库 |
Start |
Integer |
启动数据管道对象 |
为了能够动态显示管道操作的过程,需要在Uo_Pipeline用户对象的PipeMeter事件中,将Uo_Pipeline的 RowsInError、RowsRead、RowsWritten三个属性值传递给窗口对象显示出来(窗口对象见后,其名称W_CopyData)。通过窗口对象W_CopyData的自定义窗口级函数getpipemsg()实现(也可通过在w_copydata的declare中定义全局变量实 现)。
在事件PipeMeter写入下面的脚本:
w_copydata.GetPipeMsg(RowsRead,RowsWritten,RowsInError)
2.2.3创建窗口对象
窗口对象用于显示管道操作的动态信息,对管道操作进行监控,当有错误产生时,与管道对象进行交互。其名称为w_copydata。
在w_copydata中包含的控件及作用如表4。
表4 窗口对象w_copydata包含的控件
控件类型 |
控件名称 |
作用 |
静态文本 |
St_T_read |
“读入行数”提示,其text为“读入行数” |
St_t_written |
“写入行数”提示,其text为“写入行数” |
|
St_t_error |
“错误行数”提示,其text为“错误行数” |
|
St_read |
读入行数,其text为u_pipeline的RowsRead值 |
|
St_written |
写入行数,其text为u_pipeline的RowsWritten值 |
|
St_error |
错误行数,其text为u_pipeline的RowsInError值 |
|
数据窗口 |
Dw_pipe_error |
自动显示管道操作中的错误行 |
命令按钮 |
Cb_write |
启动管道操作 |
Cb_stop |
终止管道操作 |
|
Cb_applyfixes |
将Dw_pipe_error数据窗口中修复的行传输给目标表 |
|
Cb_clear |
清除Dw_pipe_error数据窗口中所有错误行 |
|
Cb_return |
关闭窗口w_copydata,并返回 |
定义w_copydata的窗口级函数getpipemsg(),访问级别为“Public”,返回值“None”,有三个参数:readrows、writerows、errorrows,类型均为long,值传递。脚本如下:
w_copydata.st_read.text=string(readrows)
w_copydata.st_written.text=string(writerows)
w_copydata.st_error.text=string(errorrows)
2.3初始化操作
初始化操作包括创建两个事务对象的实例itrans_source和itrans_dest,分别连接源和目的数据库;创建管道对象的支撑用户对象uo_pipeline的一个实例iuo_pipeline。
由于实例变量itrans_source和itrans_dest在启动数据管道操作时(在命令按钮Cb_write的clicked事件中) 也要用到,所以应该将它们定义为全局实例变量。在窗口的declare中选择instance variables,并添加以下脚本:
transaction itrans_source
transaction itrans_dest
uo_pipe iuo_pipe
初始化操作在窗口对象w_copydata的open事件中完成。在w_copydata的open事件中输入下面的脚本:
itrans_source = CREATE transaction
itrans_dest = CREATE transaction
// Profile S,为了增加通用性,参数也可以从导出的profile文件中获取
itrans_source.DBMS = "ODBC"
itrans_source.AutoCommit = False
itrans_source.DBParm ="ConnectString='DSN=s;UID=dba;PWD=ygg'"
connect USING itrans_source;
// Profile D,为了增加通用性,参数也可以从导出的profile文件中获取
itrans_dest.DBMS = "ODBC"
itrans_dest.AutoCommit = False
itrans_dest.DBParm ="ConnectString='DSN=d;UID=dba;PWD=ygg'"
connect USING itrans_dest;
//建立管道对象uo_pipe的一个实例
iuo_pipe = CREATE uo_pipe
2.4启动数据管道
启动数据管道操作在命令按钮Cb_write的clicked事件中进行,以在目标数据库建立数据表(pile_create)作为默认操作,如果出错,则进行数据表修改(pile_modify)。出错行信息会自动出现在数据窗口dw_pipe_errors中。
在命令按钮Cb_write的clicked事件中添加脚本:
iuo_pipe.dataobject = 'p_create'
integer li_start_result
li_start_result=iuo_pipe.start(itrans_source,itrans_dest,dw_pipe_errors)
//返回-3表示数据表已存在,使用修改方式
if li_start_result=-3 then
iuo_pipe.dataobject = 'p_modify'
li_start_result=iuo_pipe.start(itrans_source,itrans_dest,dw_pipe_errors)
end if
2.5处理行错误
在定义管道对象pile_Create和pile_modify时,可以设定最大出错行数,出错行数可以从1~no limit,当出错行数达到指定值时,管道操作自动停止。但在操作中,由于用户进行了误操作或管道操作执行的时间比预期的要长时,用户可以人工停止数据管道的运行。
当管道操作停止后,如果数据窗口dw_pipe_errors中有出错行,则可进行修复。
数据管道的终止执行可以在命令按钮cb_stop的clicked事件中通过执行数据管道实例对象的cancel()函数实现。脚本如下:
if iuo_pipeline.cancel() = 1 then
messagebox(“提示信息”,”终止数据管道操作失败!”)
end if
忽略错误行的操作在命令按钮cb_clear的clicked事件中进行,脚本如下:
dw_pipe_error.result()
修改数据后,重新提交工作在命令按钮Cb_applyfixes的clicked事件中进行,脚本如下:
iuo_pipeline.repair()
2.6结束操作
管道操作完成后,应该断开数据库的连接,并释放用过的实例。结束操作在命令按钮cb_return的clicked事件中进行,脚本如下:
Destroy iuo_pipeline
DISCONNECT USING itrans_source;
Destroy itrans_source
DISCONNECT USING itrans_dest;
Destroy itrans_dest
Close(parent)
3.结语
使用数据管道在应用程序中实现数据的自动迁移和备份的一般实现方法,本文进行了有益的尝试和探讨。在正确配置的实际系统中,本方法已经实现数据 的正确迁移。整个开发过程在一个窗口用户对象中完成,增加了代码的可移植性和可重用性。当然,在迁移数据的可选择性和通用性方面还有待进一步实践。
参考文献:
[1]PowerBuild7.0应用开发技术详解.王蓉等.北京:电子工业出版社,2000.3
[2]PowerBuild7.0对象与控件技术详解.王梅君等.北京:电子工业出版社,2000.3
[3]PowerBuild7.0原理与应用指南.刘红岩 何雅丽等.北京:电子工业出版社,2000.3