ADO BUG之'无法为更新定位行....' 解决之道

在Delphi中,如果使用ADOQuery插入数据没有问题, 之后对数据进行修改保存时,就会遇到“无法为更新定位行,一些值可能已在最后一次读取后已更改”的问题。

原因有这样几种:

1.在数据库设计时,为某些字段设置了默认值,在修改进行提交以后,数据库会自动修改对应字段的所有行的默认值,从而导致了数据库与数据集中数据的不一致,使ADOQuery无法对数据集进行定位。

2.数据库对应的表没有主键,输入了重复的数据以后,数据库里有两条一样的数据,从而使ADOQuery无法对数据进行定位。

解决方法:

1.修改数据库设计,不再设置默认值,为数据库表定义主键,保证其唯一性。

2.在执行完ADOQuery.Post之后,执行ADOQuery.Refresh,对于设置默认值的情况可以解决。
 (refresh后dataset中的默认值字段获得了值,跟数据库中一致了)

3.改用Insert into sql语句插入,而不是add--post方式. 但这种方式不更新其他打开该表的query, 所以要requery才行, refresh不起作用.

--------------------------------------------------------------------------
外一篇关于oracle中出现该问题的文章:
分析解决delphi的bug:“无法为更新定位行。一些值可能已在最后一次读取后已更改。”

Delphi在使用ADO操作oracle数据库时,经常会出现“无法为更新定位行。一些值可能已在最后一次读取后已更改。”的错误,一直没有找到好的解决办法,但同样得代码在SQLServer上却没有问题。上回看到了eygle 如何跟踪oracle的文章有所启发,对程序的数据库操作进行了跟踪,找到了问题的所在。

分析错误出现的情况

1.   在使用DBGrid对表进行编辑时,添加一行数据,再修改新添加行中的原来为空的一个字段(文本型),改变光标到其它行,此时提示错误。

分析:添加不报错,修改提交时报错,分析可能是执行UPDATE时报错。

2.   对一条数据中文本字段进行第二次修改时提示同样错误。

分析:第一次修改不报错,第二次就报错,两次都是执行UPDATE,区别可能就是,第一次和第二次的一些状态不同了。

跟踪ORACLE,得到执行错误时的脚本

UPDATE "测试" SET "档号"=:V00001 WHERE "档号"=:V00002 AND

"ROWID"=:V00003

Bind#0

value="eee"

Bind#1

Bind#2

value="AAAD7CAAGAAACgPAAI"

跟踪ORACLE,得到执行正确时的脚本

UPDATE "测试" SET "档号"=:V00001 WHERE "档号" IS NULL AND "ROWID"=:V00002

Bind#0

value="eee"

Bind#1

value="AAAD7CAAGAAACgPAAI"

根据以上跟踪的结果,找到了问题的所在,"档号"=’’ 和 "档号" IS NULL 在ORACLE是不同的, "档号"=’’在ORACLE 不能定位到正确的记录行,所以造成了更新的失败。

我们知道ORACLE中文本型字段有两种状态 NULL 和NOT NULL,而MSSQL中有三种状态 NULL,NOT NULL 和’’ ,这就是为何以上程序在MSSQL中运行正常,而在ORACLE中却不能正常的原因了。(注:Oracle中如设置一个文本字段=’’,Oracle会自动将其转换为NULL,但是在查询时如果这样用就不行,不知能不能算是ORACLE的一个BUG。)

为何在第一次编辑时能正确生成代码,而在第二次就不可以了。原因就是Delphi中的TField的属性IsNULL,第一次其从数据库中取出了正确的状态为IsNull=True,编辑之后,如果数值=’’,其IsNull就是False,而TAdoQuery生成更新脚本时就是根据这个属性来生成=’’和 IS NULL这两种脚本的。

找到问题,我们就可以写代码来解决问题了。分析以上问题,我们只要在使用ORACLE数据库时,在提交前,将文本字段=’’字段的IsNull=True,就可以了,我们在TADOQuery的BeforePost事件中添加代码,代码如下:

procedure TFrmData.adoqMainBeforePost(DataSet: TDataSet);

var

i: Integer;

begin

if DATA = 'ORACLE' then //自定义,标明数据库类型

for i := 0 to DataSet.FieldCount - 1 do

begin

if DataSet.Fields[i].IsNull then

exit;

if DataSet.Fields[i].DataType in [ftString, ftFixedChar, ftGuid,

ftWideString] then

if DataSet.Fields[i].AsString = '' then

DataSet.Fields[i].Clear;

end;

end;

转载于:https://www.cnblogs.com/m0488/archive/2013/04/22/3036111.html

ADO BUG之'无法为更新定位行....' 解决之道相关推荐

  1. 无法为更新定位行,一些值可能已在最后一次读取后已更改

    无法为更新定位行,一些值可能已在最后一次读取(2009-03-11 11:58:22)标签:it 报错:无法为更新定位行,一些值可能已在最后一次读取后已更改 在Delphi 7中,用ADOQuery或 ...

  2. C# ex.StackTrace 异常定位行号不显示的问题

    ex.StackTrace 异常定位行号不显示的问题 使用ex.StackTrace输出信息,如上图所示,不显示报错行号.经过测试 Debug模式下: Release模式下: Debug模式和Rele ...

  3. php如何定义的数位置,php如何实现不借助IDE快速定位行数或者方法定义的文件和位置...

    php 如何实现不借助IDE快速定位行数或者方法定义的文件和位置 借助了ReflectionMethod的一些特性,可以快速获得函数或者方法是在哪个文件的什么位置定义的,对于调试没有文档的程序来说很有 ...

  4. 当前记录集不支持更新_不断中招的你还放心升级win10吗?wi10近期更新问题及解决办法...

    .专于心 精于形. Win10用户升级5月更新后屏幕出现蓝绿伪影:或跟调节色温软件有关 随着五月更新升级范围的扩大,一些问题也是加速展现在微软面前. 现在,有不少Windows 10用户反馈称,自己升 ...

  5. 32f4 usb 升级程序_不断中招的你还放心升级win10吗?wi10近期更新问题及解决办法...

    .专于心 精于形. Win10用户升级5月更新后屏幕出现蓝绿伪影:或跟调节色温软件有关 随着五月更新升级范围的扩大,一些问题也是加速展现在微软面前. 现在,有不少Windows 10用户反馈称,自己升 ...

  6. ACCESS数据库操作必须使用一个可更新的查询 解决办法

    ACCESS数据库操作必须使用一个可更新的查询 解决办法 ACCESS数据库无法更新问题: 一般在Winxp与windows 2003 server下,文件目录的只读属性会影响网站程序写数据库操作,即 ...

  7. 辐射76服务器无响应 控制台暂停使用,辐射76更新后卡死解决方法介绍 中途卡死退出处理方法...

    原标题:辐射76更新后卡死解决方法介绍 中途卡死退出处理方法 <辐射76>在近期进行了一波游戏性的更新修复了不少的BUG和问题,不过不少玩家在更新后遇到了卡死的问题,下面就为大家带来具体的 ...

  8. svn更新路径,解决办法详细步骤,eclipse里面的更新方法,svn废弃位置,Windows环境,svn服务器地址换了,如何更新本地工作目录

    svn更新路径,解决办法详细步骤,eclipse里面的更新方法,svn废弃位置,Windows环境,svn服务器地址换了,如何更新本地工作目录 参考文章: (1)svn更新路径,解决办法详细步骤,ec ...

  9. vs2017 2019 下载更新慢的解决方法

    vs2017 2019 下载更新慢的解决方法 参考文章: (1)vs2017 2019 下载更新慢的解决方法 (2)https://www.cnblogs.com/zxs-onestar/p/1164 ...

  10. 安装慢_Origin平台安装更新慢的解决办法

    Origin平台安装更新慢的解决办法: origin开始下载更新后, [注: ProgramDate文件夹需勾选 隐藏的项目 才能显示] 首先在C:ProgramDataOriginSelfUpdat ...

最新文章

  1. 在openstack上创建第一个虚拟机
  2. Attention Mechanism
  3. 提醒一下技术人,你是不是陷入局部最优了
  4. c# 访问修饰符的访问权限
  5. 工程师实战:单片机裸机程序框架是怎样炼成的?
  6. 做形态学方法的团队_图像分割实战-分水岭分割方法和GrabCut 算法
  7. python中path的用法,python中path的用法
  8. UVALive - 6440
  9. undefined reference to `inflateInit2_'
  10. Python深度学习入门笔记(一):使用Pandas从CSV格式的文件读取数据
  11. 如何开启刷题,蓝桥杯练习系统
  12. php保存pdf旋转90度,怎么将PDF文件向左旋转90度?这款软件还有旋转功能!
  13. php百度编辑器demo,百度编辑器 Laravel Ueditor | 码农软件 - 码农网
  14. 使用Socks5代理加速爬虫访问的方法
  15. 交易者应该学习的东西
  16. Mysql 5.7.11压缩版安装及问题解决
  17. 趋势科技2014年暑期实习生笔试题
  18. 数字孪生轨道交通:“智慧化”监控疏通城市运行痛点
  19. 开篇之作之——阅读与思考
  20. Android开源—RXJava观察者设计模式

热门文章

  1. iTerm2 如何设置以单词为单位快速移动光标?
  2. JQUERY-SELECT 实现下拉框可以搜索、选择
  3. javascript在使用时要注意的东西
  4. Mysql学习第一课-mysql的定义及sql语句
  5. 自己写的一个ffmpeg时间戳分析工具
  6. TC SRM 665 DIV2 A LuckyXor 暴力
  7. 张东:大数据时代挑战与解决之道
  8. Centos5.8升级SSH到5.8p2
  9. 觉得做人累了就看看这些!不是社会错了,是你错了!写的超好!
  10. 锁开销和上下文切换开销