1、利用importfile ( )函数实现转移
PowerBuilder是一种进行C/S系统开发的优秀的前端工具,本身提供了大量的功能和函数,其中DataWindow数据窗口是其重要的组成部分,具有强大的功能,其中importfile( )函数能够完成数据的转移。
实现的过程是在服务器上创建一个同磁盘上的数据库结构相同的表,创建一个数据窗口对象(dw_fox),取数据源建立数据窗口,利用数据窗口对象本身的importfile( )函数将数据转移到数据窗口中,利用update( )函数将数据保存到服务器上所建的表中:
dw_fox. importfi1e (cipan_file_name)
dw_fox. Update ( )
其中cipan_file_name为磁盘上的文件及其路径名称。该处理简单,但是缺乏灵活性,对在服务器数据库中建立的表的结构有比较高的要求,保证严格的一致性,但可以作相应的处理将有效的数据处理后转移到自己建的表中。
2、利用ODBC连接实现转移
ODBC是一种标准的应用程序接口(API),最早由Microsoft Windows系统实现,它允许一个应用程序同时连接多个数据源,它使用标准的SQL语句作为其数据查询语句。在处理过程中先通过ODBC画板静态地建立一个ODBC连接磁盘上的Foxbase数据库,编程中创建一个本地的事务对象连接本地的数据库,通过处理后,将有效的数据送到服务器上事先设计的一个与 Foxbase数据库相类似的表中,保存有效的数据就可以了。在实际处理的过程中,各个地方的磁盘文件名是不同的,这样所连接的数据库文件名和目录都是变化的,那么在设计的时候就不能够实现将ODBC的接口固定设计出来,在处理的时候一般有两种方式,前端作一定的处理,即按照系统要求的目录和文件名称进行拷贝,为了使应用程序有更好的适应性,我们没有采取这种方式,而是另外一种方式,采取动态建立ODBC连接的方式。
在PowerBuilder的ODBC连接中需要几个重要的参数,在利用ODBC事先建立一个连接FoxBASE数据库后(如Foxbase),查看pb.ini文件时将有如下的记录:
[PROFILE Foxtran]
DBMS=ODBC
.......
DbParm=Connectstring='DSN=FoxBASE'
Prompt=0
AutoCommit=0
同样打开注册器在HKEY_CURRENT_USER SoftwareODBCODBC.INI下将会发现已经注册的FoxBASE主键,这些给我们动态地建立ODBC连接提供了重要的资料。
在具体的设置中利用PowerBuilder提供的函数注册一个ODBC的连接,然后创建一个事务对象连接本地(磁盘)的数据库,作相应的处理后将所需要的数据送到服务器上,具体的操作如下:
RegistrySet("HKEY_CURRENT_USERSoftwareODBCODBC.INI
FoxBASE", "Default Dir", regstring!, file_path)
//设置FoxBASE主键
Transaction Foxtran
Foxtran=create Transaction //下面是初始化
Foxtran.DBMS="ODBC"
Foxtran.DBParm="Connectstring='DSN=FoxBASE'"
connect using Foxtran;
其中FoxBASE是注册的ODBC的名称,Foxtran是事务对象管理中创建的用以连接Foxbase数据库的新事务,然后对事务对象进行初始化,file_path是磁盘数据库所在的路径名称(可根据用户输入的文件路径和文件名分析后取得)。利用动态创建ODBC连接同样可以同时连接其它的本地数据库如ACCESS或者Sybase SQL anywhere等,具有一定的灵活性。
3、利用数据管道实现转移
PowerBuilder的数据管道对象是在开发(利用Data Pipeline画板来完成)和运行(动态的生成)当中传输数据和数据结构的一种有效的方案。这些数据库可以是相同的DBMS或不同的DBMS,数据传输可以是插入一张完整的数据表或者表的一部分及其数据,也可以是更新已有表的数据。转换时几个重要的选项是:源数据库,目标数据库,移动数据出来的源表,数据将移到的目的表,所要完成的管道操作等。下面以在运行中使用为例来加以说明其处理的过程。
(1)建立管道对象(Pipe_copy_convert),然后建立一个管道类型的标准类用户对象u_pipeline和一个数据窗口dw_pipe_errors。在运行的过程中创建用户对象实例,对它的属性进行赋值:iu_pipeline=create u_pipelineiu_pipeline.DataObject="pipe_copy_convert"
(2)创建连接源数据库和目标数据库的事务对象,初始化连接事务对象(同上)。
;
Transaction Tran_sourse, Tran_dest Tran_sourse=create Transaction Tran_dest=create Transaction ...... //初始化 |
(3)运行数据管道及后续处理。
利用start()函数完成后,捕捉到错误后进行相应的处理,利用cancel()终止数据管道的执行。
;
iu_pipeline.start (tran_sourse, tran_dest, dw_pipe_errors) ...... //错误处理 iu_pipeline.cancel() |
利用数据管道能够比较快速的、直接的将本地数据库(包括表的整个结构或者部分以及数据)转移到服务器的数据库并保存在一个表中,在转移用户的原始档案资料的时候多采取这种方法。
4、分析本地库系统实现转移
在进行数据转换的过程中,由于各种数据的表的结构都是不一样的,以电信计费的信息费为例,不同的地区信息台使用的软件不同,数据字段几乎都是不一样的,实际的处理中也不是每一个字段的数据都有意义,或者都需要转换到服务器的数据库中,用户往往要求根据自己的需要来选择字段、计算方式以及每列的约束条件(如有些项目有最大值的限制等),利用以上的方法来处理就有些困难。在实际的处理中,我们考虑分析本地数据库的系统表,来得到本地数据库的结构,将数据库中的各个字段呈现在用户的面前。用户作出选择后,加入一定的条件,再进行处理,将利用动态SQL语句生成一个满足条件的表。这样就要求用户能够通过系统来了解磁盘数据库的内容,分析本地库的系统表后将得到较为满意的结果。
在利用ODBC连接到本地库后,发现并分析了几个系统表(System table),其中有一个表是Pbcatcol中记录着用户数据库的结构,其中的一部分如表1所示(如果表为ADDRESS (ID, Name, Address, Phone))。
表 1
pbc_tnam | pbc tid | pbc ownr | pbc cnam |
ADDRESS | Public | ID | |
ADDRESS | Public | Name | |
ADDRESS | Public | Address | |
ADDRESS | Public | Phone |
其中:pbc_tnam记录的是用户数据库的表名(Table name) (在Foxbase中一个表就是一个数据库),pbc_cnam记录的是用户数据库的列名(Column name)。
根据用户输入的文件名称,取消后缀即可得到数据库的表名,定义一个光标即可取得用户数据库的列名,将数据库展示在用户的面前,用户根据需要选择后再作处理。
;
DECLARE My_Cursor CURSOR FOR SELECT pbcatcol.pbc_cnam FROM pbcatcol ...... |
利用分析系统表来得到用户数据库的结构是一个比较有效的方法,它能够对未知的数据库结构有一个清晰的认识,而不需要事先知道它的结构。但是它仍然有一个问题,就是通过分析系统表不能得到用户数据库的列的数据类型,在转换到服务器的数据库的时候要借助用户的输入才能够确定,即提供用户必须选择的项目来确定某一个字段的数据类型。能够比较好地完成数据的转换,具有相当大的灵活性,程序并不要关心用户数据库的类型,可以广泛地使用于各种类型的数据库(Foxbase,ACCESS等)。
5、分析服务器系统实现转移
要确定一个数据库的结构,只要确定用户数据库的字段名和数据类型就可以了。利用分析本地库系统表的方式可以得到数据库的字段名,但是用户数据库的字段的数据类型仍然无法获得。通过分析Sybase服务器数据库的系统表可以得到服务器数据库中的表的字段名和数据类型。在设计的时候考虑采取两种方法相结合的办法,先利用(数据管道)Pipeline将用户本地的数据库完整地转换到服务器的数据库中的一个表,然后通过分析服务器上的系统表: Pbcatcol,Syscolumns,Systypes。其中Pbcatcol表中同前面一样记录着用户表的表名和字段名等,Syscolumns中记录着数据库中所有表的字段名(Name)、字段的数据类型(Type)、字段的长度(Length)和精确度(Prec,Scale)等。将三个表关联后可从中取得从磁盘上转换到服务器上的表的完整的结构(可以通过定义光标或者直接利用数据窗口的方式完成具体的设计)。
;
SELECT syscolumns.name, systypes.name FROM pbcatcol, syscolumns, systypes, length WHERE (syscolumns.type=systypes.type) and (pbcatcol.pbc_cnam=syscolumns.name) and ((pbcatcol.pbc_tnam= 'Address')); |
6、分析数据库文件实现转移
利用数据管道和分析服务器系统表相结合的方法能够比较完整的解决数据的转换问题,但仍然要将本地的数据库完整的转换到服务器上,增加了服务器的负担,占据了一定的存储空间。设计中我们试用了另一种方法,通过分析本地数据库本身的结构,希望有所收获。利用Visual C++以二进制的方式将数据库文件打开(此种方法只对Foxbase文件进行了分析)发现如图1所示的结构,文件存储的方式是表头和数据两个部分,表头以十六进制的0D结尾。其表头的规律是:第一个32个字节是文件头;从第二个32个字节后是第一个字段名和数据类型;第三个32字节开始又是第二个字段名和数据类型。以此类推,直到0D结束,其结构如表2所示。不足的部分添十六进制的00,其中数据类型是简写:C-Char,D-Date,L-Logical,N-Numeric,M- Memo,G-Genera1。
表 2
字段名(1~11) | 数据类型 (12~32) |
11个字节 (最多) |
一个字节 |
于是用PowerBuilder提供的文件处理函数FileOpen(),FileSeek(),FileRead(),FileClose()等,可以分析Foxbase数据库文件,得到本地数据库的字段和数据类型。对各种字段的长度可以让用户来设定,或者系统按照最大和系统的要求来设定。在服务器的数据库上来产生相应的表,利用动态的数据窗口(Datawindow)可以显示本地库的数据和处理的结果。
7、结束语
对于完成数据的转移有很多种的方法。在实际的处理过程中,要根据用户的需求和系统的设计等各个方面来考虑。其目的是要设计过程简单,而且要满足用户的需要,要求有较高的适应性和灵活性,以减少后期的维护工作。本文上述的6种方法均在系统的设计过程中得以实现,取得了较好的效果。