有關PB/Sybase開發過程中數據庫轉移介紹
摘要:針對在大型MIS系統中經常遇到將一種數據庫的原始數據轉移到服務器數據庫進行的處理問題,將本地磁盤上的Foxbase數據庫數據轉移到Sybase 11數據庫服務器為例,提出了幾種有效的方法,並對各種方法的優缺點作了一一的說明和比較。
在大型的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 SoftwareODBCODBC.INI下將會發現已經注冊的FoxBASE主鍵,這些給我們動態地建立ODBC連接提供了重要的資料。
在具體的設置中利用PowerBuilder提供的函數注冊一個ODBC的連接,然後創建一個事務對象連接本地(磁盤)的數據庫,作相應的處理後將所需要的數據送到服務器上,具體的操作如下:
ReGIStrySet("HKEY_CURRENT_USERSoftwareODBCODBC.INIFoxBASE", "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 ran_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))。
其中: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。
於是用PowerBuilder提供的文件處理函數FileOpen(),FileSeek(),FileRead(),FileClose()等,可以分析Foxbase數據庫文件,得到本地數據庫的字段和數據類型。對各種字段的長度可以讓用戶來設定,或者系統按照最大和系統的要求來設定。在服務器的數據庫上來產生相應的表,利用動態的數據窗口(Datawindow)可以顯示本地庫的數據和處理的結果。
7、結束語
對於完成數據的轉移有很多種的方法。在實際的處理過程中,要根據用戶的需求和系統的設計等各個方面來考慮。其目的是要設計過程簡單,而且要滿足用戶的需要,要求有較高的適應性和靈活性,以減少後期的維護工作。本文上述的6種方法均在系統的設計過程中得以實現,取得了較好的效果。
有關PB/Sybase開發過程中數據庫轉移介紹