淺議PB中數據窗口緩衝區與數據修改狀態(轉)散分貼解決方法

?摘 要:文章描述了PowerBuilder中數據窗口緩衝區,詳細介紹了數據窗口中行與列的修改狀態以及PowerBuilder提供的相關函數,並給出了幾則應用實例。
??關鍵詞:PowerBuilder 數據窗口 緩衝區

??中圖分類號:TP311.131

??文獻標識碼:A
 
  PowerBuilder是當今最先進的數據庫開發工具之一,它以開放性、可移植性以及易用性而聞名於世。PowerBuilder的突出特點是給應用開發人員提供了非常方便的開發環境和工具,而數據窗口技術則是其中最耀眼的閃光點。利用數據窗口,開發人員可以完成絕大多數數據操作任務。本文從數據窗口中數據的修改狀態的角度出發,介紹利用數據窗口進行應用開發的一些技巧。
  1 數據窗口緩衝區

??在應用中,每個數據窗口控件都要檢索4個內存緩衝區,它們是:

 ?·主緩衝區(PrimaryBuffer):存放檢索出來的數據,但不包括過濾掉和刪除掉的數據。

 ?·過濾緩衝區(FilterBuffer):存放從主緩衝區中過濾掉的數據。

 ?·刪除緩衝區(DeleteBuffer):存放從主緩衝區中刪除掉的數據。

 ?·原始緩衝區(OriginalBuffer):存放從數據庫裏檢索到的原始數據,它由PowerBuild在內部維護,可以利用該緩衝區中的數據進行數據恢復,在應用程序中實現Undo功能。

  2 行與列的修改狀態

??行與列的修改狀態在PowerBuilder中爲dwItemStatus枚舉類型值,它們包含:?·NotModified!:指定行或列處的信息與最初檢索出的相同。?·DataModified!:指定列或行中某列處的信息在檢索出後發生了改變。

 ?·New!:指定行是新行,但此行的列並未賦值。本狀態只適用於行,不適用於單個列。

 ?·NewModified!:指定行是新行且行中的列已經賦值。新行的狀態成爲NewModified!,既可能是用戶輸入或使用SetItem函數造成的,也可能是由於它的某列具有缺省值。本狀態只適用於行,不適用於單個列。

 ?數據窗口中行或列的修改狀態決定Update()函數將爲該行或該列產生何種類型的SQL語句。對主緩衝區和過濾緩衝區中的行,Update爲狀態是NewModified!的行產生Insert語句,爲狀態是DateModified!的行產生Update語句,只有狀態是DataModified!的列纔會包含在Update語句中。對刪除緩衝區中的行,若其狀態是New!或NewModified!,則Update語句不會爲其產生Update語句。

 ?利用函數GetItemStatus可獲得某行或某列的修改狀態,利用函數SetItemStatus可改變某行或某列的修改狀態。

 ?語法:

  dwcontrol.GetItemStatus(row,column,dwbuffer)

  dwcontrol.SetItemStatus(row,column,dwbuffer,status)

  對於如何改變狀態,PowerBuilder有一些限制,表1給出了這種限制,其中Yes表示可把初始狀態改變爲指定狀態,No則表示不可以。

表1數據修改狀態設置約束


初始狀態 指定狀態 
New! NewModified! DataModified! NotModified! 
New! —— Yes Yes No 
NewModified! No —— Yes New! 
DataModified! NewModified! Yes —— Yes 
NotModified! Yes Yes Yes —— 

  通過觀察表1,我們可以發現這樣一種情況:假設某個記錄的狀態爲New!,那麼不能直接改爲NotModified!但可先將它改爲DataModified!,然後再改爲NotModified!。

 ?利用函數RowsCopy、RowsMove可以在不同DataWindow控件(或DataStore對象)之間或同一DataWindow控件(或DataStore對象)的不同緩衝區之間複製、移動數據行。

 ?語法:

  dwcontrol.RowsCopy(startrow,endrow,copybuffer,targetdw,beforerow,targetbuffer)
  dwcontrol.RowsMove(startrow,endrow,movebuffer,targetdw,beforerow,targetbuffer)

 ?當某行在刪除緩衝區中時,或者在主緩衝區或過濾緩衝區中,並且狀態爲NewModified!或DataModified!時,其更新標誌被設置。函數ResetUpdate清除DataWindow或DataStore中主緩衝區和過濾緩衝區中的更新標誌並清空其刪除緩衝區。清除更新標誌後,所有行的狀態爲NotModified!或New!。

 ?語法:dwcontrol.ResetUpdate()

  3 應用舉例

??(1)在數據窗口中,某些列常具有缺省值,tb或我們在執行了InsertRow操作後立即使用SetItem函數爲某些列賦值。如果用戶執行了一個插入操作後立即關閉窗口會觸發closequery事件,這時會提示用戶記錄已經被修改,但用戶並沒有感覺到對數據的修改。爲避免出現這種情況,可作如下處理:

 ?intli_new_row
 ?li_new_row=dw_l.InsertRow(0)
 ?//通過SetItem函數爲列賦值
 ?dw_l.SetItem(……)
 ?//將新行的修改狀態置爲NotModified!
 ?dw_l.SetItemStatus(li_new_row,0,primary!,NotModified!)

 ?(2)在應用程序中提供Undo功能,將實現很好的用戶友好效果。本例中將數據窗口dw_l中的當前行、當前列的顯示值置爲從數據庫中檢索出的原始值:
  string ls_ori_val
 ?ls_ori_val=dw_l.GetItemString(dw_l.GetRow(),dw_l.GetColumn(),
                           &Primary!,True)
? dw_l.SetText(ls_ori_val)

 ?(3)在協調兩個DataWindow對象dw_l、dw_2的更新時,若其中一個更新失敗,應阻止重設更新標誌,以便回滾事務,一旦所有數據窗口都已成功更新,就可使用COMMIT結束該事務,並使用ReSetUpdate重新設置數據窗口的狀態標誌。
 ?Int li_ret_code
 ?li_ret_code=dw_l.Update(True,False)//阻止重設更新標誌
 ?If li_ret_code=l then
   ?li_ret_code=dw_2.Update(True,False)//阻止重設更新標誌?
    lf li_ret_code=l then
      dw_l.ResetUpdate()//清除更新標誌
      dw_2.ResetUpdate()//清除更新標誌
      COMMIT;
   ?Else
      ?ROLLBACK;
   ?Endif
 ?Endif
  (4)將數據行從刪除緩衝區移到主緩衝區,tb實現取消刪除的功能。
  ?dw_l.RowsMove(l,dw_l.DeletedCount(),Delete!,dw_l,l,Primary!)

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章