您的位置:首页 > 其它

DataWindow的数据管理与更新机制的研究与应用

2010-06-16 15:29 218 查看
1. 前言
  Power Builder是Powersoft公司推出的基于客户机/服务器体系结构的强有力的专业开发工具,自问世以来深受开发人员的好评。Data Window是Power Builder中获取专利技术的控件,它对数据处理的方法相当简洁,能处理各种显示格式,进行报表打印,对复杂的报表同样处理自如。Data Window是对数据库中的数据进行操作的窗口,它包括数据窗口控件和数据窗口对象两部分,通过它不但可以对数据库的表进行查询、检索,而且还可以进行数据的插入、删除和更新,定义数据的显示格式和编辑风格,定义数据的检条件、过滤条件、有效性规则等。因此Data Window是一个支持数据操作的封装性很好的对象。
  一般用户对数据的操作和管理均在Data Window中进行,通过Data Window,用户可以自由灵活地操作和处理数据,而作为Power Builder应用的开发人员则很有必要了解Data Window是如何操作和管理数据的,深入了解Data Window对数据的底层更新机制,全面理解Data Window的技术精华,从而灵活、有效地开发Power Builder应用程序。所以,研究Power Builder的底层数据管理与更新机制具有重大的理论价值和现实意义。

2. Data Window控件管理数据的原理

  在Data Window中可以处理用户对数据的增加、删除、修改等请求,那么在Data Window中数据是如何管理的呢?
  当光标在Data Window中移动时,Power Builder就在光标所在的当前工作单元上放置了一个编辑控件。
  编辑控件中的内容为文本,文本还没有被Data Window控件所接受,在文本中输入的数据还没有成为Data Window缓冲区中的数据,只是编辑控件中的一串字符。当用户改变了编辑控件中的内容,按回车键或Tab等离开该单元时,Power Builder将处理编辑控件中的字符,判断其是否成为有效数据。若有效则接收,把它写入Data Window当前缓冲区的当前行当前列;若无效则被拒绝,不进行写入操作。那么,Power Builder处理Data Window控件单元的文本的过程是怎样的呢?当Data Window中某一列的文本被接收,且光标移开后,将顺序发生下面的事件。

2.1 Power Builder把编辑控件中的文本转换成对应列的数据类型 的数据,若输入的数据不能转换成对应列的数据类型,就触发Item Error错误。
2.2 若转换成功,Power Builder就会用该列的有效性规则对转换 后的数据进行有效性检查。如果有效性检查失败,也会触发Item Error事件。
2.3 若数据通过了有效性检查就会触发Item Change事件,如果该 事件返回值为1,则Power Builder会拒绝该数据,并且不允许光标从该单元上移开。在这种 情况下也会触发Item Error事件。
2.4 Item Changed事件接收了输入的数据后,将触发Item Focus C hanged事件,数据就会作为一项存入Data Window的数据缓冲区中。
前一阶段完成后进入下一阶段。若某阶段未通过则跳过下面的阶段直接显示出错信息。四个阶段全完成后Power Builde自动把编辑控件中的数据放入数据窗口的响应项上,同时存入主缓冲区。编辑控件中的数据可以通过Data Window控件的对象函数Get Text()得到。

3. Data Window对象更新数据的原理

  当在Data Window中对数据做了修改后,可以使用Update函数把上次执行Update或Retrieve函数以来在Data Window中进行的所有插入、修改、删除等操作都提交给数据库。
那么Power Builder的底层又是如何对数据库进行更新的呢,要了解它就必须了解Data Window中的四个缓冲区以及当前数据存储时各个缓冲区中状态的转变情况。

3.1 Data Window的四个缓冲区

  在每一个Data Window对象中都有4个二维表作为数据缓冲区,用来存储查询到的数据,用户在Data Window中对数据处理系统内部的操作实际上都是将数据在几个缓冲区中进行修改和移动,最后,在用户提交数据库时,系统根据4个缓冲区中的信息,形成SQL的Insert、update、Delete等语句。

这四个缓冲区是:

Primary Buffer这个缓冲区存放显示在数据窗口控件中的所有行,以及这些行和列的状态。调用Data Window的Retrieve()函数和Insert Row()函数时,检索到和新插入的数据存放在这个缓冲区中。

Delete Buffer这个缓冲区保存的是用Delete Row()函数从Primary缓冲区中删除的记录。用Delete Row ()删除数据行或用Rowsmove()函数在缓冲区之间移动数据时,被删除行从主缓冲区移到 删除缓冲区。在执行Data Window的Update函数将数据窗口的修改发送到数据库管理系统时 , 被成功删除的记录均从删除缓冲区中清除。在保存数据时,删除缓冲区用于生成Delete语句 。

Filter Buffer这一缓冲区存储的是那些满足数据源定义(即满足Select语句中的条件)而不满足过滤条件的行。过滤缓冲区与主缓冲区一起在更新数据时生成所需的Insert或Update语句。

Original Buffer这一缓冲区存储的是Data Window最初执行Retrieve函数时得到的全部记录。当提交数据库时,根据Primary Buffer生成的Update语句和根据Delete Buffer生成的Delete语句都要依据这一缓冲区来构造这些SQL语句中的Where子句。

  当从数据库中读取数据时,所有数据会放在Primary Buffer中,并且会复制一份到Original Buffer中,在数据窗口中,我们只能看到Primary Buffer内的数据,任何数据的处理也都是针对主缓冲区中的数据做处理。但是要记住,不管我们对缓冲区中的数据做何种处理,除非运行Update函数,否则,缓冲区内任何数据的改变,对于后端数据库是没有任何影响的。

  Primary Buffer的记录行数通过数据窗口控件的对象函数Rowcount()得到;Delete Buffer的记录行数通过数据窗口控件的对象函数Deleted Count()得到;Filter Buffer的记录行数通过数据窗口的控件对象函数Filter Count()得到。利用数据窗口控件的对象函数Set Filter()可以动态地改变过滤条件,然后使用数据窗口控件的对象函数filter更新主缓冲区和过滤缓冲区中的数据。

  而Original Buffer由Power Builder内部维护,Power Builder所提供的所有函数都无法改变它的值。不过通过Power Builder所提供的Get Item系列函数可以读出Data Window最初从数据库中检索到的值。通过这些函数可以编程实现所谓"undo"功能。

3.2 Data Window数据项的状态值

  在数据窗口控件的主缓冲区,过滤缓冲区和删除缓冲区中,每一行和每一行中的列都有一个编辑状态标志,这个标志表示了相应行是否是新增加的行、相应列的数据是否被修改。在更新数据库时,Power Builder通过查看Data Window缓冲区中每一行的状态值来决定产生什么类型的SQL语句。可以用Get Item Status函数和Set Item Status 对这些状态值进行操纵,缓冲区有四个状态值,其中有两个用于行。

  当往Data Window中插入一行时,新插入行的状态为New!,该行中所有列的状态都为Not Modified !,当该行中某列的数据发生变化时,该列状态为Data Modified!。若Data Window中某一列设置了默认值,新插入一行时,该列状态也为Not Modified!,至少要对它做一次修改,该列的状态才会变成该列状态为Data Modified!

3.3 Data Window数据的操作

  当调用Update函数时,Power Builder根据当前缓冲区和过滤缓冲区中的各行状态产生响应的Insert或Update语句。当行状态为New Modified!时,Power Builder将产生一个Insert语句,当行状态为Data Modified!时,Power Builder将产生一个Update语句。若某列在Data Window维护的可更新列名单上,或者该列为Data Modified!时,Power Builder将更新此列。对Insert语句来说,Power Builder将对所有列进行插入操作,因此,Insert语句将包括所有的列,如果该列没有赋值,Power Builder将会插入一个空值,若数据库不允许该列为空,则会产生数据库错误。
在Data Window中用Delete Row()函数删除的行将移到删除缓冲区中。当使用Update语句向数据库提交Data Window中的数据时,对Data Window删除缓冲区中的所有行都产生一个SQL Delete语句。然而若在Delete Row()被调用前某行的状态为New!,或New Modified!,对该行将不产生Delete语句。

4.四个缓冲区在编程中的应用

  有时需要人为改变行和列的状态,其目的是为了阻止Power builder某些默认行为的发生。例如,如果事先已经从一个数据窗口拷贝某行到另一个数据窗口中,当用户对所拷贝的行又做了修改,需要将修改后的行覆盖另一数据窗口中的同一行时就应该对该行发一个Update语句,而不是Insert语句。           可以利用Set Item Statsus函数在程序中改变数据窗口行和列的状态信息,利用Get Item S tatus来获得某行某列的状态信息。
Set Item Statsus函数可以将某一列的状态从Data Modified!改变为Not Modified!,或从N ot Modified!变为Data Modified!,而对于行状态来说情况就要复杂的多。

  当把某行状态改成Not Modified!或New!时,将把该行所有列的状态都设为Not Modified!。但若不能直接将一种状态改变为另一种状态,可以间接完成。例如,如果要把某行状态从New!改为Not Modified!可以先把该行状态改为Data Modified!,然后再从Data Modified!状态改为NotModified!。要复位整个数据窗口的修改状态,请使用数据窗口控件的Reset Update()对象函数。该函数除New!状态之外,将其它状态均修改为Not Modified!。

  另外,当使用Reset函数和Retrieve函数以及改变数据对象属性时,系统将重置这几个缓冲区。例如当用户插入一个新行时,程序往往要在新插入行中的某一列中插入一个缺省的数据值,但此时用户并没有对数据做任何修改。在用户要关闭这一窗口时,如果在Close Query事件中用Modified Count函数查看数据是否修改,得到的结果是有所改变。因此,此时用户将得到一个提示信息:"是否保存所做的修改?"这样的结果是很不好的,因为用户原本没有向DataWindow中输入任何数据,但是程序却提示用户是否做保存操作。若用户选择了做保存操作,系统将形成SQL Insert语句提交数据库,原本应是空记录的行,也成了有记录的行,同时若碰上某些字段不能为空的却因没输入数据而提交了,保存操作后就插入了NULL,因此会导致数据的有效性出错。但是这一情况可以通过编程得到完美的解决:用Set Item Stats us函数将该行的状态改为New!即当新行插入并设置了缺省值以后该行的状态值为New!亦即无数据改变,因此不再提示做数据保存操作。其具体实现情况如下面代码所示:

//在数据窗口dw-1中插入一个新行
longrow1
row1=dw1Insert Row(dw1,Getrow())
dw1Set Item(row1,"discountpic",0,10)
//设置行状态为New!让程序只有在用户输入了数据时,才提示保存操作。
dw1Set Item Status(row1,0,primary!,New!)
//下面是用代码修改行列状态的例子。
该例代码将数据窗口主缓冲区第五行Salay列的状态置为Not Modified!dw1Set Item Statsus(5,"Salary",Primary!, Not Modified!)
下面的代码将数据窗口主缓冲区第五行empstatus列的状态设为Date Modified!
dw1Set Item Status(5,"empstatus",Primary,Data Modified!)

5.结束语

  数据窗口在处理数据时很有特色,它在客户机的本地内存中开辟了四个缓冲区:主缓冲区、删除缓冲区、过滤缓冲区及原始缓冲区。从数据库中检索到数据后,数据窗口根据不同情况把数据放到不同的缓冲区中。四个缓冲区各司其职,相互协作完成数据的增、删、改等操作,最后把结果提交给数据库管理系统。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: