数据窗口update失败的问题!!

yyy 2004-08-18 10:04:10
数据窗口dw_1.InsertRow(),dw_1.SetItem()等多项操作后,用dw_1.update(true,false)更新,第一次更新一般都可以成功,但是多操作几次就会出错,没有任何错误信息(sqlerrtext为空),后来发现要是一直执行Setitem一般不会出错,但是执行Insertrow后update都会出错,不知道什么原因。
...全文
434 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
mittee 2004-08-19
  • 打赏
  • 举报
回复
这个不难,你可以把检索数据的工作放在一个函数或者自定义
事件里,调用或者触发一下就可以
qiuafa 2004-08-19
  • 打赏
  • 举报
回复
学习
lzheng2001 2004-08-19
  • 打赏
  • 举报
回复
dw_1.update(true,false)这里错了,
应该用
dw_1.update()
workhand 2004-08-19
  • 打赏
  • 举报
回复

【查了一下】


Rows changed between retrieve and update.
并发操作出现的问题

需要退出再做一遍才可以 :)
(转贴)
PowerBuilder中的并发控制

PowerBuilder中可以通过数据窗口的更新属性(Update Properties)来实现并发控制。打开 DataWindow 画笔板,点击 Rows->Update Properties菜单,进入“Specify Updatae Properties”对话框,其中“Where Clause for Update/Delete”组合框中的三个选项就是三种处理数据并发问题的策略。

1、选项“Key Columns”:

这种情况是比较更新前后Table的关键字是否发生了变化,即当前数据库中关键字的实际值和最初查询的值做比较,如果没有改变,则可以更新,反之不能更新。

如用户A将员工号为100的职员的salary字段值改为1200并保存后,B用户也将员工号为100的职员的salary字段值改为950并点击“存盘”按钮,我们可以看到数据窗口sqlpreview事件中的sqlsyntax返回如:

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100

因为关键字id=100没有发生变化,Where条件成立,更新成功,将A用户的修改覆盖,salary值变为950元,员工损失了200元。显然这样没有达到并发控制的目的,未能保证数据的完整性。



2、选项“Key and Updateable Column”:

这种情况是比较更新前后Table的关键字和可修改(更新)的列值是否发生了变化,如果没有一项发生改变,更新成功;反之,若数据库中当前值中若任一项与数据窗口最初检索出的值不一致,则更新失败。对于此例,因所有字段都是可修改(更新)的,即检测是否有任一字段变化。

同上,当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'

显然,id字段没有改变,而可修改(更新)列之一salary的值经A用户修改存盘后,已由1000变为了当前的1200,where条件不成立,因此更新失败,并弹出出错信息如下:

Row changed between retrieve and update.

No changes made to database.

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'

此时点击《刷新》按钮,我们可以看到,salary的值仍为1200,达到了并发控制的目的,保证数据的完整性。



3、选项“Key and Modified Columns”:

这种情况是比较更新前后Table的关键字和要修改(更新)的列值是否发生了变化,如果没有改变,更新成功,反之更新失败。对于本例,即判断关键字id和将要修改字段salary是否发生变化。

同上,当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000

这里id字段没有改变,而此次将要修改的列salary值已由1000变为了1200,where条件不成立,因此更新失败,并弹出出错信息如下:

Row changed between retrieve and update.

No changes made to database.

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000

此时我们点击《刷新》按钮,我们可以看到,salary的值仍为1200,也达到了并发控制的目的。



再举一个例子:

如果A用户更新的是备注notes字段,而B用户更新的是薪水salary字段,按照业务,这种操作是允许的,而在PB中会如何处理呢?

1、对于选项“Key Columns”: 因为关键字没有改变,更新成功。

2、对于选项“Key and Updateable Column”:

当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'

这里,id字段没有改变,salary字段也没有改变,但可修改(更新)列之一notes的值经A用户的修改,已由“软件开发”变为了“硬件维护”,where条件不成立,因此更新失败,系统将报出错信息。

此时点击《刷新》按钮,可以看到,salary的值仍为1200,notes的值为“硬件维护”。



3、对于选项“Key and Modified Columns”:

当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:

UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000

这里,id字段没有改变,而将要修改的列salary值也没有改变(A用户只是修改了notes字段),where条件成立,因此更新成功。

此时点击《刷新》按钮,可以看到,salary的值为950,notes的值为“硬件维护”。注意这里B用户只是修改salary字段,并不修改notes字段,因此notes保留了A用户修改后的值。



从上面例子中我们可以得出如下结论:

1、“Key Columns”选项在控制数据完整性方面最弱,它所允许的并发操作是最多的,所禁止的并发操作发生的可能性非常小,只有当主键被更改后才起并发控制作用,当一条记录的关键字改变了才进行控制,这显然没有多大意义。实际上这种方法一般只在单机版的应用程序中使用,而在Client/Server模式中是很少使用的。

2、“Key and Updateable Columns”的是PB的默认选项,控制最为严格,可以实现最安全的并发控制,充分保证数据的完整性,但它也会禁止我们做一些本当允许的并发修改(如上面所说的第二例),是并发能力最差的方法。

3、“Key and Modified Columns”选项可以说是前两者的折衷,在控制数据完整性和严格性方面比第一项强,比第二项弱,在允许的并发操作数量方面比第一项少,比第二项多。

至于在程序中选取哪一种控制比较合适,我们应该根据应用的具体情况来选择。

对于并发控制,我们还需要在程序中捕获 DBMS 的出错号,再显示相应的错误信息,否则PowerBuilder给出的那些出错信息,一般用户是看不懂的。这项功能可在数据窗口的dberror事件中编写代码实现。
amekoxiao 2004-08-19
  • 打赏
  • 举报
回复
设置好后要resetupdate(),commit,否则rollback
workhand 2004-08-19
  • 打赏
  • 举报
回复
真的要每次都retrieve吗?只要设好dw的update属性就应该没问题吧
jackxrh 2004-08-19
  • 打赏
  • 举报
回复
你不要用 update(true,false) ,直接用 update() 或update(true,true)就可以了 .


这里有一个更新状态复位的问题 . 或者用 update(true,false) 成功后用 resetupdate()
来复位 dw 的更新状态
cxwsoftware 2004-08-19
  • 打赏
  • 举报
回复
一般都是刷新一下的!
c8 2004-08-19
  • 打赏
  • 举报
回复
mittee(最后一条大白鲨) 说的没错
c8 2004-08-19
  • 打赏
  • 举报
回复
看看并发控制,一般的解决办法就是update之后马上retrieve
stoneriver 2004-08-19
  • 打赏
  • 举报
回复
if dw_1.update()=true then
commit;
else
rollback
end if
yyy 2004-08-19
  • 打赏
  • 举报
回复
Update时经常出现 Row Changed between retrieve and update 这个错误!
yyy 2004-08-18
  • 打赏
  • 举报
回复
怎么刷新啊?每次都非要用retrieve刷新吗?我的retrieve条件很多啊
mittee 2004-08-18
  • 打赏
  • 举报
回复
没有任何错误信息,是因为不是数据库的问题。
是因为数据窗口没有用好,例如:你update之后没有把
数据窗口刷新一次,数据窗口显示的数据和数据表里已经不一样了。

1,108

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧