Row changed between retrieve and update令人费解.

fengwei813 2011-03-12 09:31:58
Row changed between retrieve and update.
No changes made to database.
UPDATE bom_mb SET item_id = '040650', item_name = 'A108经济左固定座', quantity = 1.000000
WHERE temp_item_id = '04M001' AND item_id = 'Y3.0010' AND item_name = '镜背漆唐山威克'
AND meas_unit = 'P' AND quantity = 5.000000 AND itemfac = 'R'

我在数据窗口点保存的时候 出现如题症状、我这个是单机状态,虽然出现这个提示、但是我的数据窗口保存成功了、触发器也正常触发了,数据上达到了预期效果,但是PB前台保存出现这个问题 触发的是trigger: if @itemfac ='R'部分

在另一种情况下点保存按钮不会 出现这个提示, 后台对应的是触发trigger if @itemfac ='B'or @itemfac='A' 。数据同样达到了预期。
我的数据窗口 Where 条件 选择的是 Key and Updateable Columns KeyModification 选择的是 update 方式。
自我感觉程序上应该没有 在数据窗口检索后 和 按保存这间 没有二次update 改变缓冲区中的值。
两种按保存的情况唯一的不同就是触发了 不同触发器中的 语句段




CREATE trigger bom_mb_update
on bom_mb for update
as

Declare @temp_item_id VarChar(40),
@new_item_id VarChar(40),
@old_item_id VarChar(40),
@item_name VarChar(40),
@quantity decimal(18,6),
@itemfac VarChar(40),
@pare_item_id VarChar(40)
Select @temp_item_id = temp_item_id, @new_item_id=item_id,
@item_name = item_name, @quantity= quantity ,@itemfac= itemfac
from inserted

Select @old_item_id = item_id
from deleted

if @itemfac ='B'or @itemfac='A'
begin
update bom set item_id= @new_item_id, item_name=@item_name, quantity= @quantity
where pare_item_id = @temp_item_id
and item_id = @old_item_id
--print '@@rowcount'+cast(@@rowcount as char(5))
end


if @itemfac ='R'
begin

--
Declare pare_id_cursor CURSOR for
select item_id from bom
where pare_item_id = @temp_item_id --创建游标
For UPDATE OF item_id,item_name,quantity --定义可更新列
Open pare_id_cursor
--执行第一次取数操作、将游标定位到第一行记录
Fetch next from pare_id_cursor into @pare_item_id
WHILE @@FETCH_STATUS = 0
begin
begin
update bom set item_id= @new_item_id, item_name=@item_name, quantity= @quantity
where item_id = @old_item_id
and pare_item_id = @pare_item_id
--定位到下一行记录
end
Fetch next from pare_id_cursor into @pare_item_id
end

close pare_id_cursor --关闭游标
deallocate pare_id_cursor --释放游标资源
end
commit

PB 保存代码


dw_1.AcceptText()


if dw_2.ModifiedCount()=0 and dw_2.DeletedCount()=0 then

MessageBox("提示信息","尚无增加、删除或修改,无需保存!")
return
end if
//dw_2.ResetUpdate()
if dw_2.update()=1 then
Commit;
MessageBox("提示信息","dw_2 保存成功!")
else
RollBack;
MessageBox("提示信息","保存失败!")
end if
...全文
442 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengwei813 2011-03-14
  • 打赏
  • 举报
回复
// Profile oac-sql
SQLCA.DBMS = "MSS Microsoft SQL Server 6.x"
SQLCA.Database = "oac"
SQLCA.LogPass = <******>
SQLCA.ServerName = "127.0.0.1"
SQLCA.LogId = "sa"
SQLCA.AutoCommit = False
SQLCA.DBParm = ""
这个是我对sqlca的设置SQLCA.AutoCommit = False 那么就是说DML语句 不自动提交,但是为什么又会冲突呢……?
fengwei813 2011-03-14
  • 打赏
  • 举报
回复
谢谢楼上的各位、问题原因我找到了,
close pare_id_cursor --关闭游标
deallocate pare_id_cursor --释放游标资源
end [/b]commit

我的触发器最后一行 有一个]commit 就是它引起这个错误的,把它去掉就行了。

我推测原因 数据窗口update()也会向数据库commit 一次。 触发器又commit 一次.所以有点冲突吧……

各位老师如有见解、畅所欲言啊!分析得准确得给分。
fengwei813 2011-03-14
  • 打赏
  • 举报
回复
顶一下, 没有解决啊,不知从何下手了……
sail0918 2011-03-14
  • 打赏
  • 举报
回复
在数据库中: update table set…是更新一个表中的数据。update 是dml语句的一种。insert, delete, select 也都是dml语句。
create table, create view ,alter table等等都是ddl语句。 commit :将事务提交。
每一个事务中可以有多个dml语句。同一个事务中,所有的dml语句要么同时提交(永久更新数据库中的数据),
要么同时回滚(取消数据修改,恢复原来的数据)。 ddl语句有个特性,每一个ddl语句后面都隐含的带有一个commit语句。
所以事务中不要包含ddl语句,或者谨慎使用。 在pb中 dw.update()是datawindow的一个方法,
由pb自动的生成了update, insert, delete等dml语句,并在数据库中执行。
dml的执行通过transaction对象进行(sqlca是pb定义的一个全局transaction对象)。
transaction对象有一个属性 (sqlca.autocommit)
if sqlca.autocommit=true then //pb执行每个dml语句后都会自动带有commit语句。
if sqlca.autocommit = false then //pb执行每个dml语句后都不会带有commit语句,由程序员自行控制事务的提交。
end if
以前的帖子中,有人提到:在做了update后,系统的数据就发生了永久修改,是因为sqlca.autocommit = true的缘故
fengwei813 2011-03-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dawugui 的回复:]
在最前面加上:

dw_1.settransobject(sqlca)
[/Quote]
我实际更新的是 dw_2 dw_1.AcceptText()写的没有用。

那我就加一个dw_2.settransobject(sqlca) 还是老样子。
fengwei813 2011-03-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zjl8008 的回复:]
原因是数据窗口update时 update properties为kdy and updatable columns 并发控制依赖条件列数据发生了改变,
可以通过设置数据窗口update properties 为 key columns
只依赖主键更新表即可
[/Quote]

这样到时不容易出现这个错误,但是key columns 对并发并不合适,这样写不是最佳方案
zjl8008 2011-03-12
  • 打赏
  • 举报
回复
原因是数据窗口update时 update properties为kdy and updatable columns 并发控制依赖条件列数据发生了改变,
可以通过设置数据窗口update properties 为 key columns
只依赖主键更新表即可
dawugui 2011-03-12
  • 打赏
  • 举报
回复
在最前面加上:

dw_1.settransobject(sqlca)
sbigwolf 2011-03-12
  • 打赏
  • 举报
回复
你的表里面有默认值了。最好在程序外边将默认值附上。要不保存成功后retrieve一次。
永生天地 2011-03-12
  • 打赏
  • 举报
回复
CREATE trigger bom_mb_update
on bom_mb for update
as

set nocount on--加这句

611

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder DataWindow
社区管理员
  • DataWindow社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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