浅议PB中数据窗口缓冲区与数据修改状态(转)散分贴解决方法

浅议PB中数据窗口缓冲区与数据修改状态(转)散分贴
浅议PB中数据窗口缓冲区与数据修改状态

阎强*吴燕萍*范逢曦*


--------------------------------------------------------------------------------

�おふ� 要:文章描述了PowerBuilder中数据窗口缓冲区,详细介绍了数据窗口中行与列的修改状态以及PowerBuilder提供的相关函数,并给出了几则应用实例。
�おす丶�词:PowerBuilder 数据窗口 缓冲区

�おぶ型挤掷嗪牛�TP311.131

�おの南妆晔堵耄�A
 
  PowerBuilder是当今最先进的数据库开发工具之一,它以开放性、可移植性以及易用性而闻名于世。PowerBuilder的突出特点是给应用开发人员提供了非常方便的开发环境和工具,而数据窗口技术tb则是其中最耀眼的闪光点。利用数据窗口,开发人员可以完成绝大多数数据操作任务。本文从数据窗口中数据的修改状态的角度出发,介绍利用数据窗口进行应用开发的一些技巧。
  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)在数据窗口中,某些列常具有缺省值,或我们在执行了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)将数据行从删除缓冲区移到主缓冲区,实现取消删除的功能。
  ��dw_l.RowsMove(l,dw_l.DeletedCount(),Delete!,dw_l,l,Primary!)

  作者:*讲师,山西医科大学计算机中心,030001太原
  收稿日期:1999-10-08
 

你可能感兴趣的:(缓冲区)