大家好!
   问题:在applyupdate(0)更新入库单(主从表)时,一切正常,由于要增减库存,所以在明细表上编写了触发器,问题也因此出现,在更新时出现:record not found or changed by another user错误!在SQL中调试触发器正常,请问问题出在那?
   因为时间紧迫,我就尝试了别的处理方式和解决办法,大体如下,但也引出了一些问题,希望能解答:
   1、改为用非主从表或雀巢表,对带有触发器的明细表applyupdate(0)出现同样错误。
   2、去掉触发器,在DataSetProvider的afterapplyupdate事件对更新解包,可是明细表的更新是以字段的方式存在主表更新包中,问题是如何对主从delta如何解包?
   3、改为用非主从表或雀巢表,去掉触发器,分别更新,在连接明细表的dataSetProvider的afterapplyupdate中可对细目数据解包,从而可以通过程序增减库存。但不足处是通过程序增减库存好象没有被包含在内在的事务中,那如何在多层中自己控制事务,并不与内在事务冲突?

解决方案 »

  1.   

    谢谢yashenJXF!   但触发器中只更新库存表,没有对入库单的主明细表进行更新操作。入库单有两个表:w_rkd_maim和w_rkd_detial,库存表w_kcb。
      

  2.   

    问题相同,网上的答案乱七八糟,主要有:时间格式问题(和数据库有关,字符串问题(''=null),触发器错误,但是我觉得是delphi自己内部的错误,因为clientdataset要维持这种主从关系,那么在provider 上要进行一些限制,这种机制不公开,造成我们不能用dataset随心所欲解决问题,但是如果你把provider 的resolvetodataet 为false,他自己更新就不会造成问题.我现在还没有找到很好的答案,因为上面的答案都是乱搞的.项目从开始就遇到很多别人遇不到遇到了也很少有人给出正确方法的问题,真他妈的烦.我在delphibbs上看了50篇贴子,都是废话.疯了.搂主给我点分呀,算是今天有点收获.呵呵
      

  3.   

    看看我的解释,可能不全对,供参考
    http://expert.csdn.net/Expert/topic/1964/1964802.xml?temp=.9070703
      

  4.   

    leon2k(LEON) 的问题跟这个同类, 但我觉得这种情况没有在内delphi 出现 record changed by another user 的原因是更新不到"一条"记录
    leon2k(LEON) 贴中解释了其中大部分问题那么 delphi 是通过什么判断更新了几条记录? 在 ms sql server 中有 EffectRecords 返回, 是0 就是record changed by another user. 可是 ms sql 恶心之处就是触发器也影响这个返回值, 也就是说你的触发器中最后一条语句的影响行数是 0另一种可能就是 Update effect more than 1 record, 也是触发器最后一条语句造成, 这种情况可以设 DataSetProvider Options 中 AllowMutipleRecordUpdates
      

  5.   

    我刚遇到过,同意comanche(太可怕) 的。
      

  6.   

    DataSetProvider在更新记录时都要查找原来的记录,如果找不到就报告record not found or changed by another user的错误表示记录被修改了。
    DataSetProvider定位原记录时有三中方法(也就是WHERE语句中的条件)upWhereAll:即所有字段原来的值匹配
    upWhereChanged:改变了的字段原来的值匹配
    upWhereKeyOnly:主键字段原来的值匹配(TQuery不能用)在单用户时,有两种情况也会产生不正常的record not found or changed by another user错误
    1、使用自动增长字段,新增记录保存后立即修改记录又保存时
    2、日期字段,特别是数据库中产生的日期,主要的毫秒的问题可以使用upWhereChanged,upWhereKeyOnly更新的方式来解决问题,
    另外也可以设置upWhereAll的更新方式,然后设置字段是否作为原记录的查找条件。办法为:Field.ProviderFlags := Field.ProviderFlags-[pfInUpdate];另外有些字段在客户端临时使用,不想更新到数据库中,可以使用办法Field.ProviderFlags := [];
      

  7.   

    嗯,的确,我以前作的时候也出现同样的问题,很讨厌SQL Server的一些东西。
    想说的已经被comanche(太可怕)说了:)
      

  8.   

    在触发器中使用了修改或者选择语句,SQL server 返回了执行触发器更改的信息,而不是你要提交的信息,而Delphi依靠返回值判断是否成功。建议设置成触发器 Set nocount on 后再进行数据操作,但这样如果触发器存储出错将错误将不会被捕获。
    另外还有一个错误是在operfume(橘子香水) 说得,如果数据库中有缺省值,不管是自增还是什么,只要增加后客户端和数据库端不符,必然出错。
      

  9.   

    哦!你做的方法和你一样啊。完全一模一样。我的库存也是在通过触发器来实现的,
    也是用三层架构开发的。提交方法也一样。可是我没有问题啊。
      你可以先找问题出在哪里,先把触发器注释掉,不要让它执行,看看是否有出发器的原因。
    第二:假如你的主键不是自增长,可以考虑用updatemode为upWhereKeyOnly,要不就用upwhereall,但这种方法假如两人以上同时对同一单据操作时,就会出现你现在提示的问题.
    最终的原因是没有找到要更新的记录.
      

  10.   

    深受其害,最后也是通过dataprovider  updatemode=upWhereKeyOnly来解决,
    补充一名TQuery能用的不过要加永久字段
      

  11.   

    你个问题曾经困绕的很长时间,你福了!
    问题出在你的触发器上,由于你在更新记录时,触发器中的SQl语句在更新相关表时,没有找到相关记录,此时你的更新操作就会出错。
       解决此问题就是在触发器中先检测相关表的记录是否成在,不成在时就跳过好了。
      

  12.   

    建议更新删除全部通过主关键子来定位记录(upWhereKeyOnly),主键的值由添加记录时自己产生。我后来就是这样做的,现在已经基本避免了这个问题。我用“年月日时分秒随机数”来产生RecID,时间取数据库的时间,随机数取了一个新产生的UUID中的一部分,这样基本保证不会有重复的RecID产生,产生重复的RecID的可能性总是应该有的吧,只是非常非常小了。
      

  13.   

    记录重复,找到的记录不只一条,错误产生,我觉得说和数据库ms sql关系不明确,因为oracle也是这种问题,更改 updatemode 根本不管用。奇怪!