ADO出错:无法为更新行集定位(100分)

N

Niki

Unregistered / Unconfirmed
GUEST, unregistred user!
DOConnection.BeginTrans;
try
MasterTable.UpdateBatch;
DetailsTable.UpdateBatch;
ADOConnection.CommitTrans;
except
ADOConnection.RollbackTrans;
raise;
end;
第一次保存执行以上代码,因为违反DetailTable的PK规则报错,然后回去处理完毕,再
按保存,执行到MasterTable.UpdateBatch时出错:“无法为更新行集定位:一些值可能已
在最后读取后改变。 ”请问各位这是什么原因造成的?
 
原因是因為你第一次rollback了數據庫操作,所以後台沒有mastertable的那條數據
但是前台又已經更新了recordset的狀態,不是處於dsInsert了,它以為後台有一條
對應的數據,所以當你第二次update時,它找不到後台的對應紀錄,就報告說給別人
刪除或者修改了
 
那有什么可解决的方法吗?
 
ADO Bug.
可以先SaveToFile,出错后LoadFromFile,查我的贴子。
 
我试过用Cancel代替竟然OK没事.
 
是数据库的默认值在作怪,在绑定控件自动更新时,
数据库有些字段的默认值就更新到了数据库中,而绑定控件没有刷新造成以上错误。
解决方法:去掉数据库中的默认值即可。另外一点是数据库中少做约束,充许空设为TRUE
必填字段设为FALSE,如一定要做约束,就在程序中做。这样可以减少很多意外错误!

'无法为更新行集定位一些值可能已在最后读取后改变'
这个问题应该是被讨论很多次了,其实它不关构件事,不关数据库的事,只是你的程序有
问题而已,不管是BDE还是ADO,在数据更新时,它都会转换成SQL语句与后台的数据库打
交道,例如一个更新操作,当你在客户端修改了一些数据,而后Post的时候,BDE或者ADO
这些数据引擎会生成类似的语句:'Update tablename set field1=*** where ....',问题
的关键在于where子句,在BDE中是根据ttable的Updatemode属性控制怎样生成where子句的
而在Ado中是利用TField的ProvideFlag属性来控制,如果你的客户端程序没有注意到这些
问题的话,就很可能导致上面的错误。例如你在数据库定义时设置了字段A的默认值,而你
在客户端新增一条纪录时没有对字段A赋值,这样你在客户端缓冲中的数据就与数据库中的
不同了,当你下次再对该条纪录更新时,问题就来了,where子句中A的值就会根据客户端
赋为空,这样就会导致根据where子句定位不到数据库中的纪录,而Delphi就会认为这可能
是由于你在从数据库取下数据到你发出Post命令之间可能有另外的人更改了该条纪录
 
To niki:
可不可以先update detail表?
 
可以用query完成对表的修改
然后把table重新open一下
 
多人接受答案了。
 
顶部