计算机应用研究
APPLICATION RESEARCH OF COMPUTERS
2000 Vol.17 No.3 P.45-47




PowerBuilder/Sybase系统开发中的数据库转移
陈新安　张继棠
摘　要：针对在大型MIS系统中经常遇到将一种数据库的原始数据转移到服务器数据库进行的处理问题，将本地磁盘上的Foxbase数据库数据转移到Sybase 11数据库服务器为例，提出了几种有效的方法，并对各种方法的优缺点作了一一的说明和比较。
关键词：客户机/服务器 ODBC Pipeline 系统表
　　在大型的MIS系统中大多是采用客户机/服务器(C/S)的网络体系结构，在该系统中数据集中存储在服务器的数据库中。开发新的MIS系统的时候，数据的采集和录入是一个重要的部分。以电信计费系统为例主要有以下几个方面：1)原始数据的分拣处理，处理的对象主要是磁盘、磁带，或者光盘的二进制数据。2)以往系统中的档案数据和参数数据的转移处理，以减少用户的输入量和因为人工输入所带来的错误，处理的对象主要是Foxbase、Access等数据库文件。3)信息台或者其它部门送来的以Foxbase、Access等文件存储的费用文件，如168信息台送来的费用数据等。
　　本文中将结合PowerBuilder/Sybase系统开发的实例，重点介绍2)，3)两种情况的处理过程(即完成本地数据库文件向服务器数据库中的转移)中所采取的几种方式，以及各种方式的具体设计方法，说明了每种方法的普遍性和针对性，并对其优缺点作了比较。
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 Software\ODBC\ODBC.INI下将会发现已经注册的FoxBASE主键，这些给我们动态地建立ODBC连接提供了重要的资料。
　　在具体的设置中利用PowerBuilder提供的函数注册一个ODBC的连接，然后创建一个事务对象连接本地(磁盘)的数据库，作相应的处理后将所需要的数据送到服务器上，具体的操作如下：
RegistrySet("HKEY_CURRENT_USER\Software\ODBC\ODBC.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_tnampbc tidpbc ownrpbc cnam
ADDRESS　PublicID
ADDRESS　PublicName
ADDRESS　PublicAddress
ADDRESS　PublicPhone

　　其中：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种方法均在系统的设计过程中得以实现，取得了较好的效果。
陈新安(重庆邮电学院科研所 重庆 400065)
张继棠(重庆邮电学院科研所 重庆 400065)
参考文献
1 杨孝如等编. Sybase数据库系统管理指南. 北京:中国水利出版社, 1997
2 [美] Gallagher, S, Herbert, S.著, 曹 康译. Powerbuilder 5.0程序设计大全. 北京: 机械工业出版社, 1997. 9
3 Powerbuilder Handbook, Sybase公司
收稿日期：1999年8月20日
