【PB 】“Row changed between retrieve and update” 经典错误处理

处理方法一:

 

This is a common but frustrating error that can create real problems. The cause for this error is one or more of the following:

  1. A primary key for the table is not listed in the Update Properties for the DataWindow.
  2. The primary key selected allows and has duplicates.
  3. The Update Properties for the DataWindow are improperly set for the needs of the application.
  4. The data did actually change.

  If no primary key is listed, this is usually the result of either the DataWindow being created on a table that did not have a primary key when the DataWindow was created or the DataWindow was created and Allow Updates was not checked and later checked.

  NOTE: If at a later time, the Allow Updates is checked and you select the Table to Update, the Updateable Columns and Key Columns MUST be selected since they are not automatically selected.

  There are cases that the primary key selected is not a "true primary key" in that there can be duplicates records for each key. In this case the error will only occur when there are actual duplicates for the selected key. Often this error will go undetected for a long time until a duplicate value is present. This is a hard one to find since the error will occur on the duplicate value only. This appears to be an intermitted error.

  Specifying the WHERE clause for update/delete

  Sometimes multiple users are accessing the same tables at the same times and in cases, they may be actually accessing the same data at the same time. This may be a desired situation and the correct update/delete specification will protect the data from corruption.

  Key Columns:

  This is the least restrictive and will data corruption. This can only be safely used in single user environments and in multi-user environments when the developer can be 100% sure that only one user at a time will access the data.

  The danger of this is that since the key column is the only column specified in the WHERE clause, another user can change the data after you retrieve it and when you save, your data will over write the other users data. The only warning you would get is if the key column changed, which is very unlikely.

  Key and Updateable Columns:

  This is the PowerBuilder default and provides the greatest level of granularity but may be too restrictive for the needs of the application. The WHERE clause contains ALL the updateable columns that were selected in the Update Properties of the DataWindow NOT just the updated (modified) columns.

  This will guarantee that only one user can update a row at a time. The problem may arise when two users retrieve the same row and each changes different data elements (i.e. one user updates the address of the customer and another updates the middle name). The first user to save the data will be OK and the other user update will fail.

  Key and Modified Columns

  This is usually a good setting for most multi-user applications. This allows for multiple users to access the same row and both make changes to different data elements of the row.

  This would prevent the problem above (i.e. one user updates the address of a customer and another updates the middle name). With this setting, both users would be able to successfully save the data without any negative impact on the other users data.

  Correcting Changed Data

  To correct data errors caused from data changing between retrieve and update (except for duplicate keys) the following method is an example of what can be employed:

  If a row is changed, the DbError event will be triggered with a value of –3 in the argument sqldbcode and the row number of the failure in the argument row. A message can be displayed to the user and the row highlighted for the user to see. Allow the user the option to re-retrieve the changed row or discard it. If the user chooses to re-retrieve the changed data, use the ReSelect() PowerBuilder function. This will re-retrieve ONLY the row specified. This will allow the user to see the changes to the row and permit them to make any additional changes they desire.

IMPORTANT: PowerBuilder will stop the update process upon encountering the first error. The update process can be re-called or stopped at this error. It is usually best to continue the update process. This will update the database with all other changes and/or mark any other error rows. If the row that caused the error is in the Filter buffer, you must unfilter it if you want the user to correct the problem.

  Code a –1 as the return value for the DbError event, this will suppress the default PowerBuilder error box and allow you to display your own message.

 

处理方法二:

 

引用:http://www.hur.cn/Article/2011/123504.html

Row  changed  between  retrieve  and  update  这个问题一直困扰着我,我也遇到过很多次这类的问题,并且也有不少人问过。我自己认为是数据窗口对象update的设置的问题,因为我就是通过改动update选项改好的。  
我具体讲解一下update  property中各个选项的意思:   
Update属性详解:    
大多数情况下,您的应用程序将在网络环境下运行。有可能会有多个人同时使用一个程序。在这种情况下使用数据窗口应注意并发控制问题。 
数据窗口的并发性控制可以用"rows"菜单的"Update    Properties"项进行设定。       
1.    Allow    Updates:如果选中,则整个数据窗口允许修改,否则不允许;       
2.    Table    to    Update:在多表查询时,用该项选择要设置的表名;       
3.    Where    Clause    for    Update/Delete:这项设置是对数据库并发控制最重要的一项,要仔细设置。  
当调用数据窗口的Update方法时,数据窗口使用SQL语句将数据结果传递到数据库系统,这项设置决定在SQL语句的where子句中使用哪些列作为整条记录的标志。  
(a)Key    Columns:仅仅使用关键字作为整条记录的标志。在网络环境下不推荐使用此选项。如果两个用户同时修改了同一条记录,后进行保存操作的人会把先保存的人所做的修改"抹掉"而毫无察觉。如果选择Key    Columns,那么Update对应的SQL语句是:    
Update    A.xh,    A.xm,    A.csrq,    A.py       
Set    ...    //用户修改后的新值       
Where    A.xh    =    ...    //用户修改前的旧值     
如果被修改的不是xh列,那么后一个用户将察觉不到前一个用户所做的修改。 
(b)Key    and    Updatable    Columns:使用关键字和所有可更新列作为记录的标志。   
采用(a)中的例子,Update对应的SQL语句将是:       
Update    A.xh,    A.xm,    A.csrq,    A.py       
Set    ...    //用户修改后的新值       
Where    A.xh    =    ...       
And    A.xm    =    ...       
And    A.csrq    ...       
And    A.py    =    ...    //用户修改前的旧值   
在这种情况下,后一个用户的Update将不能成功执行。  
(c)Key    and    Modified    Columns:使用关键字和所有已更新列作为记录的标志。 
功能和(b)很相似,不同点在于(b)的前端执行速度快,数据库端慢;而(c)则刚好相反。  
4.    Key    Modification:该项设置决定了更新数据库的方法。     
(a)Use    Delete    then    Insert:先删除,再插入。       
(b)Use    Update:直接修改。       
建议使用(b)选项。       
5.    Updatable    Columns:用来选择"可更新列",这里所做的选择与3.(b)对应,没有选中的列将不会出现在Update语句中。 
6.    Unique    Key    Columns:用来选择关键字,这里所做的选择与3.(a)对应,没有选中的列将不会出现在Update语句中。   
---------------------------------------------------------------   
原因:执行dw_1.update()之前,表中的数据被其它人修改过的话就可能会出现这种情况    
什么情况下发生这种错误是由dw的update  properties  的设置决定的,   
关键因素就在这里    
表1:  a,b,c,d  列(在updatable  columns中选中全部列)   
a为key列(在unigue  key  columns  中设置)    
关键是where  clause  ...中的设置   
(a)Key    Columns:仅仅使用关键字作为整条记录的标志。  当选择这种方式时,只有a字段的值在你update()之前发生改变,才会引起这个错误  
b)Key    and    Updatable    Columns:使用关键字和所有可更新列作为记录的标志。  使用这种方式更新,最容易引起这种错误,因为只要a,b,c,d任何一个可更新的列由其它人改变了,就会引起错误.   
c)Key    and    Modified    Columns:使用关键字和所有已更新列作为记录的标志。假如:  你修改了b列,那么,在你执行update()之前,如果a,b中任何一个列由其它人改变了,就会引起这个错误.  这种情况下,如果a,b列没被其它人修改,而c,d列被修改了,则不会引起错误.  
---------------------------------------------------------------   
但是,有些时候,是单击版开发,数据改动全部由开发者控制,基本上不存在多用户同时使用的问题,也会发生Row  changed  between  retrieve  and  update  这样的错误,原先由高人指点过一二,但是也不是很清楚,请高人再指点一下  
---------------------------------------------------------------   
哪怕是单机版的程序,同样有可能出现这个错误!    
1.检查本程序中是否有多个事务对象,假如两表同时读取表的数据,事务a对表更新了,这时dw用事务b再去更新就会发生这个错误.    
2.有时候有些朋友,在开发的时候,打开了两个PB,(特别是对database操作),  另一个程序运行    
时也有可能出现这个错误    
3.对于dw如果用setitemstatus()  或  update(false,false)  之类的语句,很容易会引起这种错误    
4.如果程序中有语句修改了数据窗口的original缓冲区的值,同样会引起这个错误    
以上是我的经验总结,其中1,3条是最容易出现的
欢迎转载,但请保留出处,本文章转自[华软源码],原文链接:http://www.hur.cn/Article/2011/123504.html

 

处理方法三:

引用:http://hi.baidu.com/xqjtprevkxbbtvq/item/e34cce0a999575d11ef046d2

Row changed between retrieve and update

Row changed between retrieve and update.

No changes made to database.

DELETE FROM dbo.Overtime_Request WHERE factory_id = 23 AND department_id = 'CL' AND section_id = 1 AND overtime_date = '20081014' AND overtime_reason = '????' AND sign_by1 IS NULL AND sign_by2 IS NULL AND sign_by3 IS NULL AND Create_By = 'afen liu' AND Modify_By IS NULL

Row changed between retrieve and update 错误出现的常见原因2006-07-26 22:36       新手在在pb数据窗口编程中,可能会遇到Row changed between retrieve and update 这种错误提示。说明某个数据在retrieve和update之间数值发生改变,导致无法更新。

       其中以下是最常见的原因:因为在实际编程中,由于设计考虑不周,导致某列在pdm生成后存在改变长度或者精度的情况;结果:数据窗口中某列的长度(格式) 与 数据库中的不一致。最终是出现如题所示的错误。

       我们知道,Datawindow的更新属性 分为3种情况:

(1)Key Columns  

          选择这种更新方式,如果出现这种情况的唯一可能就是,主键在数据窗口与数据库之间出现不一致,在数据窗口的sql语句中将主键列先去掉在重新选上,就可解决问题。

(2)Key and Updateable Columns

          检查主键 和 所有可修改 的列。如(1)处理。

(3)Key and Modified Columns

           检查主键 和 要修改 的列。如(1)处理。

当然如果在(2)(3)情况下,也要考虑数据库的并发情况。


四 另外有一个原因就是dw数据窗口提交的update语句有问题,如里边的where条件有问题,可以按提示错误的条件查询一下看看有没有数据,有可能是查询条件本身就没有数据,
(我的系统用的字体是简体,但是我连接的服务器用的是繁体字,查询条件中有些条件可能是乱码,繁体字引起的)


其他分析
Row changed between retrieve and update 这个问题一直困扰着我,我也遇到过很多次这类的问题,并且也有不少人问过。我自己认为是数据窗口对象update的设置的问题,因为我就是通过改动update选项改好的。
我具体讲解一下update property中各个选项的意思:
Update属性详解:

大多数情况下,您的应用程序将在网络环境下运行。有可能会有多个人同时使用一个程序。在这种情况下使用数据窗口应注意并发控制问题。   
数据窗口的并发性控制可以用"rows"菜单的"Update  Properties"项进行设定。   
1.  Allow  Updates:如果选中,则整个数据窗口允许修改,否则不允许;   
2.  Table  to  Update:在多表查询时,用该项选择要设置的表名;   
3.  Where  Clause  for  Update/Delete:这项设置是对数据库并发控制最重要的一项,要仔细设置。   
当调用数据窗口的Update方法时,数据窗口使用SQL语句将数据结果传递到数据库系统,这项设置决定在SQL语句的where子句中使用哪些列作为整条记录的标志。   
(a)Key  Columns:仅仅使用关键字作为整条记录的标志。在网络环境下不推荐使用此选项。如果两个用户同时修改了同一条记录,后进行保存操作的人会把先保存的人所做的修改"抹掉"而毫无察觉。如果选择Key  Columns,那么Update对应的SQL语句是:   
Update  A.xh,  A.xm,  A.csrq,  A.py   
Set  ...  //用户修改后的新值   
Where  A.xh  =  ...  //用户修改前的旧值   
如果被修改的不是xh列,那么后一个用户将察觉不到前一个用户所做的修改。   
(b)Key  and  Updatable  Columns:使用关键字和所有可更新列作为记录的标志。   
采用(a)中的例子,Update对应的SQL语句将是:   
Update  A.xh,  A.xm,  A.csrq,  A.py   
Set  ...  //用户修改后的新值   
Where  A.xh  =  ...   
And  A.xm  =  ...   
And  A.csrq  ...   
And  A.py  =  ...  //用户修改前的旧值   
在这种情况下,后一个用户的Update将不能成功执行。   
(c)Key  and  Modified  Columns:使用关键字和所有已更新列作为记录的标志。   
功能和(b)很相似,不同点在于(b)的前端执行速度快,数据库端慢;而(c)则刚好相反。   
4.  Key  Modification:该项设置决定了更新数据库的方法。   
(a)Use  Delete  then  Insert:先删除,再插入。   
(b)Use  Update:直接修改。   
建议使用(b)选项。   
5.  Updatable  Columns:用来选择"可更新列",这里所做的选择与3.(b)对应,没有选中的列将不会出现在Update语句中。   
6.  Unique  Key  Columns:用来选择关键字,这里所做的选择与3.(a)对应,没有选中的列将不会出现在Update语句中。
---------------------------------------------------------------
原因:执行dw_1.update()之前,表中的数据被其它人修改过的话就可能会出现这种情况

什么情况下发生这种错误是由dw的update properties 的设置决定的,
关键因素就在这里

表1: a,b,c,d 列(在updatable columns中选中全部列)
a为key列(在unigue key columns 中设置)

关键是where clause ...中的设置
(a)Key  Columns:仅仅使用关键字作为整条记录的标志。 当选择这种方式时,只有a字段的值在你update()之前发生改变,才会引起这个错误

b)Key  and  Updatable  Columns:使用关键字和所有可更新列作为记录的标志。 使用这种方式更新,最容易引起这种错误,因为只要a,b,c,d任何一个可更新的列由其它人改变了,就会引起错误.

c)Key  and  Modified  Columns:使用关键字和所有已更新列作为记录的标志。假如: 你修改了b列,那么,在你执行update()之前,如果a,b中任何一个列由其它人改变了,就会引起这个错误. 这种情况下,如果a,b列没被其它人修改,而c,d列被修改了,则不会引起错误.
---------------------------------------------------------------
但是,有些时候,是单击版开发,数据改动全部由开发者控制,基本上不存在多用户同时使用的问题,也会发生Row changed between retrieve and update 这样的错误,原先由高人指点过一二,但是也不是很清楚,请高人再指点一下
---------------------------------------------------------------
哪怕是单机版的程序,同样有可能出现这个错误!

1.检查本程序中是否有多个事务对象,假如两表同时读取表的数据,事务a对表更新了,这时dw用事务b再去更新就会发生这个错误.

2.有时候有些朋友,在开发的时候,打开了两个PB,(特别是对database操作), 另一个程序运行

时也有可能出现这个错误

3.对于dw如果用setitemstatus() 或 update(false,false) 之类的语句,很容易会引起这种错误

4.如果程序中有语句修改了数据窗口的original缓冲区的值,同样会引起这个错误

以上是我的经验总结,其中1,3条是最容易出现的

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值