根据当前应用程序的需要和数据完整性的需要去改变DataWindow的更新选项。
要改变DataWindow对象执行更新操作的方式,可从Rows菜单下选择Update Properties,打开Specify Update Properties对话框。(如下图)
对话框分为5块内容:
1.指定允许更新选项及要更新的表
如果DataWindow中的数据不止是查询,需要更新的话,勾选Allow Updates,并在Table to Update下拉框指定要更新的一张表,下拉框的默认选项是数据源中的表或者视图。如果视图含多张表,必须指定视图中的一张表。
2.指定可以更新的列和键列
在Updateable Columns框中选蓝要更新的列,如果在数据源中拥有多于一张的表,用户仅能更新其中一张表中的各列,尽管所有的列名都出现在列表框中。
在Unique Key Column(s)框选择能唯一标识行的列(或复合列)。如果在数据源的SQL Selection List中已经指定了主键标,用户可以单击Primary Key按钮。
3.指定执行更新和删除SQL时的where子句(Where Clause for Update/Delete)
Where Clause for Update/Delete组合框包含了三个单选按钮,它们为维护数据的完整性提供了三种选项,并为数据库加锁提供了不同的选择。当某行被选择时,用户可以通过DataWindow对象来提供完整性保护而不是给某行或某页上锁(取决于数据库加锁机制)并防止其他用户检索该行。这三个选项为:Key Columns, Key and Updateable Columns和Key and Modified Columns。
3.1 Key Columns
指定了该选项,DataWindow将只使用在Unique Key Column(s)框中指定的键标列。此选项通常用于单用户应用程序中。当PowerBuilder生成Update或Delete语句时,它将比较某行检索的原始键标列值和当前数据库中此行的键标列值,如果两个值相等,更新和删除操作才会成功。
例如:假设Malcolm和Jonathan从顾客表检索到下列行,Customer_Id为主键,姓名,状态和地区为可更新列:
Customer_Id:110
Customer_Name: Simon Herbert
Status:Perferred
Region:Midwest
如果Jonathan将地区从Midwest改成Southeast,将使用键标列产生以下UPDATE语句:
UPDATE customer SET region = "Southeast" WHERE customer_id = 110 --Key Column;
此UPDATE语句将成功地被执行。如果Malcolm也要改变此行(例如,将地区变为Northwest),也会成功执行,但会出现完整性问题。Jonathan的改变将被覆盖,因为键标列没被改动。因此,这个示例中,用户拥有高度并发性(两个用户都可访问和更改数据),但数据的完整性却非常差。
Malcolm改变此行时产生的UPDATE语句:
UPDATE customer SET region = "Northwest" WHERE customer_id = 110 --Key Column;
3.2 Key and Updateable Columns
指定了该选项,PowerBuilder生成Update或Delete语句时,将比较原始键标列值、任何可更新列的原始检索值和当前数据库中这些列的值作比较。如果值都相等,更新和删除操作才会成功。这是推荐使用的方法,因为它提供了高度的数据完整性。
UPDATE customer SET region = "Southeast" WHERE customer_id = 110 --Key Column AND name = "Simon Herbert" --Updateable Column AND status = "Perferred" --Updateable Column AND region = "Midwest" --Updateable Column
Jonathan的更新操作将会成功。如果Malcolm又想改变地区,并试图进行更新,更新操作将会失败,因为WHERE子句没有改变,但是地区值现在是Southeast而不是Midwest。使用Key and Updateable Columns,尽管并发程度很低,但数据完整性却要高得多。
3.3 Key and Modified Columns
指定了该选项,PowerBuilder生成Update或Delete语句时,将比较原始键标列值、将要更改的可更新列的原始检索值和当前数据库中这些列的值作比较。如果值都相等,更新和删除操作将会发生。此方法是前两者的折衷形式。对于同一示例,如果两用户都想改变同一行的相同的列(例如region),第一个更新操作成功,第二个将失败,SQL语句将如下所述:
UPDATE customer SET region = "Southeast" WHERE customer_id = 110 --Key Column AND region = "Midwest" --Modified Column
如果前一个更新执行后,接着另一用户修改同一行记录的状态字段,由Preferred改为Exceptional,SQL语句如下所示:
UPDATE customer SET status = "Exceptional" WHERE customer_id = 110 --Key Column AND status = "Preferred" --Modified Column
这个更新操作将会成功,尽管数据已经改变了(region不同了)。因此在这种情况下数据完整程度低而并发程度高。此选项可用于两个用户同时修改相同的行时的情况,只要他们改变的是不同的列数据。
4 指定键列的修改方式(Key Modification)
指定的是如果用户改变了键标列值,更新操作将怎样发生。两个选项:Use Delete Then Insert和Use Update。
第一个选项是在删除了列以后,再用新的键值插入一个新的行。此选项减少了在数据库中重新组织的工作量,但它有着潜在的问题。如果主键是另一张表的外键并被指定为级联删除,用户可能就不想使用Use Delete Then Insert了。
警告:除了有触发级联删除的可能性之外,如果用户只检索表列中的一部分,update选项还是有用的。如果用户仅仅检索表20列中的5列并改变了主键值,使用Use Delete Then Insert选项会引起整行被删除,而且没有被检索的15个列中的数据将被丢失。
第二个选项将更新行中的键值。新的键值包含在更新过程中,和其他数据在一起,这就防止了外键和级联删除的问题。首选使用Use Update选项。
5 指定标识列(Identity Column)
此列表框用于为下拉列表中所指定的列(通常是键标列)生成序号。此选项仅仅用于支持序号生成的DBMS(也称为自增列)。通常不指定,选择None。
警告:如果用户指定了一个列为标识列,就不要将其选作为一个可更新列。如果确实想将该列选作可更新列,则对数据库执行的任何UPDATE都将失败。
补充实验:
新建一个DataWindow,指定第三点的Key and Updateable Columns,用户A和用户B同时更新同一行记录,用户A更新成功。而用户B接着提交更新时会收到报错Row changed between retrieve and update。无法更新。报错截图如下:
而指定为Key Columns,用户A、B都检索出同一条记录,则用户A更新成功,用户B更新也会成功且将A的修改覆盖了。如果用户B与用户A没有沟通的话,用户A就会感到莫名其妙,为什么我修改的信息被覆盖了。用户B也不曾知道该记录曾被A修改过。数据完整性体验极差。