在實際問題中,我們常常遇到資料庫中的一些表是使用者在程式運行期間動態產生的,若要對這樣表中的資料進行操作,就要運用動態資料視窗對象,值得提到的一點是,在動態資料視窗對象產生時,其標題區(Header Band)中的文本不能直接顯示成漢字,這的確是一點遺憾,不過這個問題可以通過映射的方法得到解決。
一、 問題的提出
設有如下兩張表:
A表中的記錄是使用者可以在程式運行期間進行自由增加、修改、刪除和更新的,B表中的屬性(即:欄位)由A表中的記錄決定並動態建立,而且,能夠方便地對B表中的資料提供漢化的操作介面。當然,將B表建立為下表
也是可以的,但是,在動態產生資料視窗對象時,其標題區(Header Band)中的文本不會顯示成漢字,而是一些亂碼,反而不利於問題的解決。
二、 問題的解決
1、 動態建立B表的解決
我們要動態建立B表,就要構建動態SQL語句。何謂動態SQL語句?資料庫應用程式通常進行確定的工作,因此在編寫和編譯時間,就可以確定完整的SQL語句,但當需要使用PowerBuilder不支援的嵌入SQL語句(如DDL語句),或者在編譯時間不知道語句的具體格式或參數,則在運行時構成SQL語句,這類語句被稱為動態SQL語句。
動態SQL語句的格式:
EXECUTE IMMEDIATE SQL statement [Using Transation Object];
參數說明:
SQL statement 包含一條有SQL語句的字串
Transation Object 事務對象
2、 動態資料視窗對象建立及標題區(Header Band)中文本漢化的解決
(1) 在程式運行時,我們可以調用Create函數動態產生資料視窗對象。格式如下:
DataWindowControl.Create(Syntax{,Errorbuffer})
參數說明:
DataWindowControl 將在其中建立資料視窗對象的資料視窗控制項名
Syntax 資料視窗對象原始碼
Errorbuffer 用於儲存錯誤資訊的字串
(2) 由於標題區(Header Band)中文字框的名稱是對應細目區(Detail Band)中相應列的名稱加上"_t"構成的,而細目區(Detail Band)中列的名稱又是相應表的屬性的名稱。因此,我們能夠使用遊標(Cursor)取出A表中的ywm和zwm的值,然後使用映射的方式替換標題區(Header Band)中文字框的文本(Text)屬性,從而使標題區(Header Band)中文字框的文本顯示為相應的漢字。
三、 一個簡單的例子
在PowerBuilder 6.5和MS SQL Server 6.5的環境下,使用一個簡單的例子實現上述的觀點,限於篇幅,只列出主要介面及關鍵程式。
1、"動態建立B表"按鈕對應的代碼是:
int li_i=1,li_count
string ywm[],zdlx[],ls_temp,ls_sql
//使用遊標(Cursor)從資料庫的表中擷取ywm和zdlx的值並儲存於數組ywm[]和zdlx[]中
select count(*) into :li_count from a;
DECLARE a_cur CURSOR FOR SELECT ywm,zdlx FROM a order by ywm;
OPEN a_cur ;
FETCH a_cur INTO :ywm[li_i], :zdlx[li_i] ;
do while sqlca.sqlcode=0
ls_temp=trim(zdlx[li_i])
choose case ls_temp
case "1"
ls_temp="char(10)"
case "2"
ls_temp="numeric(7,2)"
end choose
zdlx[li_i]=ls_temp
ywm[li_i]=trim(ywm[li_i])
li_i++
FETCH a_cur INTO :ywm[li_i], :zdlx[li_i] ;
loop
close a_cur;
//建立B表和主鍵(Primary Key)
ls_sql="create table b"+"("+ywm[1]+" "+zdlx[1]+" not null,"&
+"constraint pk_b primary key ("+ywm[1]+"))"
execute immediate:ls_sql;
//增加B表的列
for li_i=2 to li_count
ls_sql="alter table b add "+ywm[li_i]+" "+zdlx[li_i]
execute immediate:ls_sql;
end for
2、"動態建立資料視窗對象"按鈕對應的代碼是:
string syntax,sqlselect,errmsg,ls_col1,ls_col2,ls_name,ls_b;
//動態建立資料視窗對象DataWindow
ls_b="b"
sqlselect="select * from "+ls_b;
syntax=sqlca.syntaxfromsql(sqlselect,"style(type=grid)",errmsg);
dw_1.create(syntax)
//漢化標題區(Header Band)文本
DECLARE v_cur CURSOR FOR SELECT ywm,zwm FROM a order by ywm;
OPEN v_cur ;
FETCH v_cur INTO :ls_col1, :ls_col2 ;
do while sqlca.sqlcode=0
ls_name=ls_col1+'_'+'t'+'.'+'text'+'='+'"'+ls_col2+'"'
dw_1.modify(ls_name)
FETCH v_cur INTO :ls_col1, :ls_col2 ;
loop
close v_cur;
dw_1.settransobject(sqlca);
dw_1.retrieve()
四、 結束語
利用PowerBuilder的動態資料視窗對象的技術應用,可以解決實際中資料庫的動態資料處理問題,從而使應用程式具有更好的互動性和適應性,若稍加變動,用途是十分廣泛的。