在PowerBuilder环境下实现数据的同步更新

时间:2022-10-16 06:04:04

在PowerBuilder环境下实现数据的同步更新

摘要:PowerBuilder环境下默认只能更新一个数据表,如果数据窗口对象对应多个表,则PowerBuilder定义每个表的所有列都不能够更新,并且所有列的Tab值都为0,使用户不能修改数据。本文提供了一种在PowerBuilder环境下多表同步更新的方案。

关键词:PowerBuilder 多表更新 数据窗口对象

0 引言

当一个数据窗口被创建时,PowerBuilder会自动地设置它的更新属性为可更新或者不可更新,这取决于两个标准:一个是看这个数据窗口对象是否对应一个表还是对应多个表;另外一个是看表的主键是否被数据窗口对象选中。因为数据窗口对象只能更新一个表,所以,如果数据窗口对象只对应一个表,那么PowerBuilder就自动定义这个表中的所有列都是可更新的,并且此时所有列的Tab值均不为0,以便用户能够修改数据。可是,如果数据窗口对象对应多个表,则PowerBuilder定义每个表的所有列都不能够更新,并且所有列的Tab值都为0,使用户不能修改数据。

当用户的数据窗口对象对应多个表时,如果PowerBuilder设置的更新属性不符合用户的要求,也就是说用户想这个数据窗口对象能够更新数据库,那么用户必须手工修改数据窗口对象的更新属性。

1 设置数据对象的更新属性

要定义一个数据窗口对象的更新属性,可以选择Rows|

Update Properties菜单项,将弹出Specify Update Properties对话框,如图1所示。

对话框中各更新属性的含义如下:

1.1 Allow Updates(允许更新)复选框:用于指定该数据窗口是否具有可更新能力,选中此复选框后,才可以设置其他属性。

1.2 Table to Update(可更新的表)下拉列表框:每个数据窗口在每一时刻只可更新一个表的数据。此下拉列表框就是用来指定当前数据窗口可更新的表。

1.3 Unique Key Columns(键列)列表框:键列用来标识表中将被更新的记录的一列或多列,PowerBuilder在生成数据库的更新语句时,将用这些键列构成WHERE子句。键列可以是表的主键,也可以不是。

1.4 Updateable Columns(可更新列)列表框:用来设置当前数据窗口对象当前可更新的表中哪些字段具有可更新能力。如果某一列未被指定为可更新列,那么,即使在数据窗口中修改了此列的数据,它也不会向数据库提交。

1.5 Where Clause for Update/Delete(用于更新的WHERE子句)组框:该组框内的三个单选按钮提供了三种构造Where 子句的方法。不同的Where子句可以提供不同级别的数据完整性保护。①Key Columns单选按钮:是让Where子句中只包括主键列。这些主键列在窗口的右下角的Unique Key Columns的列表框中指定。在这种情况下,PowerBuilder只把原来检索出来的关键列的数值与数据库中的关键列的数值进行比较,如果这些值匹配,则能够更新数据库。②Key and Updateable Columns单选按钮:是让Where子句中只包括主键列和可更新列。主键列在Unique Key Columns的列表框中,所有可更新列在Updateable Columns列表框中选择。在这种情况下,PowerBuilder把原来检索出来的关键列和可更新列的数值同数据库中这些列的值进行比较,如果匹配,则能够更新数据库。③Key and Modified Columns单选按钮:是让Where子句中包括主键列和所有已经做过修改的列,这种情况下,PowerBuilder把原来检索出来的关键列和已经更新的列的数值同数据库中这些列的数值比较,如果自上次检索以后,这些列中任意一列的值与数据库中的值不匹配,则不能更新数据库。

1.6 Key Modification(键列的更新)组框:该组框内的两个单选按钮是用来决定当关键字被更新时的更新方式。有两种方式:Use Delete then Insert单选按钮,先使用Delete语句删除,然后再用Insert语句插入;Use Update单选按钮是直接使用Update语句对主键列进行更新。

①缺省设置是Use Delete then Insert,表示当一个主键列被修改时先删除这一条数据,然后再用Insert语句插入数据到数据库中。不过值得注意的是,如果有其他表的数据依赖于这个表的主键时,例如一个公司的“学生信息表”是依赖“班级表”中的“班级编号”这个主键列,那么在使用Use Delete then Insert时,首先会删除“班级表”中的一条数据,而且也会删除“学生信息表”中与“班级表”中有相同的班级编号的那条数据,这样就会造成数据库中数据的丢失,所以,在使用这个方式时应该根据具体的应用和数据库设计来选择。②Identify Column(标识列)下拉列表框。许多数据库管理系统支持这样一种列。当向表中插入一条新记录时,此列的值由数据库管理系统自动指定,称之为标识列。不同的数据库管理系统支持的标识列的类型也不同。例如,Adaptive Server Anywhere允许定义其值自动增加的列。在Specify Update Properties对话框中可以指定一个标识列。这样,当在数据窗口中新插入一列并提交后,PowerBuilder会自动把此列的值带回并显示出来。否则,需要重新检索才能看到此列的值。

2 多表更新解决方案

①创建数据窗口对象,选择合适的数据源和显示风格,保证数据窗口具有更新能力。②选取多表中所需的数据项(各表的主键和非空列一定要包含进去)。③修改所需数据项的Tab Order,保证其在数据窗口中是可修改的(TabOrder值不为0)。④选取菜单Rows|Update Properties,定义数据窗口的更新属性(定义主表的列为可更新列)。⑤使用update(true,false)对主表进行更新。⑥切换可更新的表(辅表)、主键、列,将主表的主键、列设为不可更新。⑦使用update()对辅表进行更新。

3 实现数据同步更新

3.1 建库建表。在一个数据窗口对象中实现对两个表的数据更新主要是动态修改数据窗口的Update属性以及getitemstring()、setitem()函数的使用。以数据库mydata.db中的数据表tabel1和table2为例,在库中建表table1(班级表),表结构如下:bjname(班级名称)/char/20(主键)/不能为空,rs(人数)/integer/不能为空,dy(导员)/char/8/允许为空,输入记录。建表table2(学生表),表结构如下:xh(学号)/char/6(主键)/不能为空,name(姓名)/char/8/不能为空,csrq(出生日期)/date/允许为空,bjname(班级名称)/char/20/不能为空(外键),通过bjname与表table1建立链接。table1(班级表)为主表,table2(学生表)为辅表。即先输入班级名称,才能输入该班级的学生,输入记录。

3.2 界面设计。设计多表更新窗口w_test,界面设计如图2所示。

3.3 建立数据窗口对象。建立数据窗口对象d_update,风格:Freeform,数据源:SQL Select,选择数据表:table1、table2,选择列xh,name,bjname(这三列来自table2),bjname,rs(这二列来自table1),单击工具栏上的 钮,修改各列的Tab Order值为10、20、30……依此类推,删除table2_bjname列及该列的标题,选取菜单Rows|Update Properties,按图1所示设置各项更新属性。设置数据窗口对象中所有标题边框为凸起,所有列边框为下凹,均为左对齐。

3.4 关键代码实现。在多表更新的操作中,除按3.3正确设置属性外,还有一个关键环节,就是代码实现数据同步更新。图2的“存盘”按钮的Clicked事件的代码为:

int n,row1

string bjm

n=dw_1.update(true,false)

if n>0 then

commit;

messagebox("提示","table1班级表存盘成功!")

else

rollback;

messagebox("提示","table1班级表存盘失败!")

end if

dw_1.object.datawindow.table.updatetable="table2" //切换更新数据表

dw_1.object.table2_xh.key="yes"//设置可更新的主键

dw_1.object.table2_xh.update="yes"//设置可更新字段

dw_1.object.table2_name.update="yes"

dw_1.object.table2_bjname.update="yes"

dw_1.object.table1_bjname.key="no"//设置不可更新的主键

dw_1.object.table1_bjname.update="no"//设置不可更新的字段

dw_1.object.table1_rs.update="no"

row1=dw_1.getrow()//获取当前行的行号

bjm=dw_1.getitemstring(row1,"table1_bjname")

dw_1.setitem(row1,"table2_bjname",bjm)

n=dw_1.update()

if n>0 then

commit;

messagebox("提示","table2学生表存盘成功!")

end if

4 结语

本文中数据源选择SQL Select,每个数据列的名称前都加了表名,删除table2_bjname列,即删除了table2表的bjname列,数据窗口中保留了table1表中的bjname列,使用getitemstring()函数取出输入到table1的bjname值,用函数setitem()写入到表table2中。

参考文献:

[1]柯建勋,蔡毅,邓格林.PowerBuilder8.0基础篇[M].北京:清华大学出版社,2002.

[2]柯建勋,张涛,邵亮.PowerBuilder8.0进阶篇[M].北京:清华大学出版社,2002.

[3]张伟聪.基于PowerBuilder的图书馆办公自动化系统设计[J].医学信息,2006(09).

作者简介:

王超(1972-),女,辽宁朝阳人,信息工程系副主任,副教授,研究方向:软件开发。

上一篇:南海:办好每一所学校,教好每一位学生 下一篇:宝安:以教育均衡促社会公平