来自:gxdx, 时间:2003-6-2 8:15:00, ID:1915570 | 编辑 [显示:小字体 | 大字体]  一个表里的记录竟然存在不公平待遇,一张表里有些记录ApplyUpdate(-1)有效,后台数据库的确
更新了,而另一些记录无论怎么ApplyUpdate(-1),后台数据库都是没动静。
我的这张表除了一个自动编号的字段外,其余的都是可空字段,而数据输入时应该都是合法的。
请问这是怎么一回事呢?  
来自:bitd, 时间:2003-6-2 8:19:00, ID:1915580
你用什么数据库?可能和这个自动编号的字段有关,
我用interbase也发生过类似问题  
来自:HHSH, 时间:2003-6-2 9:20:00, ID:1915804
 这没什么奇怪的。要看对这些记录进行了什么操作,更新失败的原因是什么。
举个简单的例子:假如你对两批记录都执行delete操作,在后台更新时,在第一批记录中很快地找到了你要找的记录(唯一),于是ApplyUpdate(-1)便成功了。而在第二批记录中,在后台更新时,查找到的记录可能不是唯一的(例如,表没主键时就可能出现这种情况),ApplyUpdate(-1)就更新失败了。最好是用错误窗口看一下,很容易捕捉到更新失败的错误。具体怎么做,介绍三层系统的书
上一般都有。  
来自:Dephic, 时间:2003-6-2 9:26:00, ID:1915826
同意HHSH,的说法,你提交之后,不是数据库没有动静,我想应该是主键冲突等情况引起更新失败!你要跟踪一下你后台的代码,先查明是什么原因导致提交失败,再处理吧!  
来自:gxdx, 时间:2003-6-2 11:03:00, ID:1916293 | 编辑
请问HandelReconcileError()是哪个unit里的呢?  
来自:HHSH, 时间:2003-6-2 11:38:00, ID:1916476
uses uniterror 就OK了!
 
来自:LiChaoHui, 时间:2003-6-2 11:40:00, ID:1916492
看这个函数的返回值,非零就是有错误  
来自:gxdx, 时间:2003-6-2 12:33:00, ID:1916677 | 编辑
可我想知道错误的信息。
UnitError不行啊,找不到该单元  
来自:gxdx, 时间:2003-6-2 12:44:00, ID:1916713 | 编辑
啊,我知道怎么得到错误信息了。
showMessage(e.Message)返回的错误信息是:
Record not found or changed by another user
但明明存在而且只有我一个人在弄的也。怎么回事啊?  
来自:hcm0790, 时间:2003-6-2 13:06:00, ID:1916803
象ApplyUpdate這樣的函數玩玩還可以, 千萬不要用在產品中. 還是自已寫吧.  
来自:gxdx, 时间:2003-6-2 13:42:00, ID:1916960 | 编辑
不会吧?会死人的也。时日无多啦。要交货了。惨。  
来自:LiChaoHui, 时间:2003-6-2 14:11:00, ID:1917070
ApplyUpdate很正常啊,我都用这个,没有发现特别的问题,
 
来自:gxdx, 时间:2003-6-2 20:31:00, ID:1918679 | 编辑
n年以前添加的数据都可以Update,现在insert可以,后台有新数据,但insert进去的数据就
再也不可能Update了。就是新添加的数据不可以update,老是说:Record not found or changed
by another user。大侠们救命啊。不然迟点你们只能在新闻头条上看到我了。  
来自:menxin, 时间:2003-6-2 20:32:00, ID:1918688
服务端是什么,adoquery?要设置一下  
来自:gxdx, 时间:2003-6-2 21:44:00, ID:1918909 | 编辑
是啊,是adoquery啊。要怎么设置啊?  
 

解决方案 »

  1.   

    问题在这...
    n年以前添加的数据都可以Update,现在insert可以,后台有新数据,但insert进去的数据就
                                                                ^^^^^^^^^^^^^^^^^^^^  
    再也不可能Update了。就是新添加的数据不可以update,老是说:
    ^^^^^^^^^^^^^^^^^^
    Record not found or changed
    by another user你可以 insert 后 refresh 一下, 再试试 Update...原因是那个自动增长字段, Midas 并不适合用这种类型的字段
      

  2.   

    以前我也碰到类似这样的问题,
    后来我将自动编号的字段改成GUID类型就OK了。你可以参考一下。
      

  3.   

    我用的是Sql server里的int identity啊。
    找不到GUID类型哦。
      

  4.   

    to gxdx: 那是绝对不可能的, 知道了问题发生的原因就会明白, 当新加一记录时 AutoID 的字段是由服务器填的, 客户机并不知道真实值是什么(当然你刷新记录后没问题), 刚更新完马上修改, 那就可能发生客户机跟服务器这个字段内容对不上, 所以 record changed by another, 实际上就是你自已
      

  5.   

    呵呵,我用sql server也遇到过这种情况,减价一下你数据库中,表的“列名”中是否使用了“()、[]、{}”,如果有这些符号的话,数据是不会update的
      

  6.   

    呵呵,我用sql server也遇到过这种情况,检查一下你数据库中,表的“列名”中是否使用了“()、[]、{}”,如果有这些符号的话,数据是不会update的
      

  7.   

    to  comanche(太可怕) :
    不是这个问题。因为我就算事先在Sql server里先填好数据,然后打开客户端来修改也一样update不了。不过有几条n年前加的数据就可以。to liven(铁板) :
    我保证没有这回事。
    在大富翁论坛上有人帮我解决了问题。他要我在服务端的AdoQuery的afterOpen事件里加以下代码:
    var
     i: Integer;
    begin
     for i := 0 to Dataset.FieldCount - 1 do
       if Dataset.Fields[i].CanModify then
         dataset.Fields[i].ProviderFlags := [pfInUpdate];
     这样就没事了,所有数据都可以更新了。但我依然不明白问题的实质。哪位大侠能否告诉我这样做的原因是什么?
      

  8.   

    楼上代码的意思就是设置字段的标志为需要更新,
    没有pfInUpdate标志的字段将不被更新,
    不过,我从未遇见过这样的问题!pfInUpdate是默认的!
      

  9.   

    对了,楼主你的DataSetProvider的更新模式是...?
      

  10.   

    之前是UWhereAll,我改成UWhereChanged后,更新没问题了,但删除却又有问题了。原来更新不了的数据现在变成删除不了,而原来可以更新的数据就删除得了。
    UWhereAll、UWhereChanged和UKeyOnly三者都是什么意思啊?有什么不同?
      

  11.   

    UWhereALL: 在定位记录时使用所有的字段,
       即在更新和删除记录的Where子句里包括所有的字段,
       如果其它用户在你取得数据后又更改了数据,你将得到一个无法定位记录的错误。
    UWhereChanged: 在定位记录时只使用修改过的字段,
       如果其它用户已更改了你要更新了数据,你将得到一个无法定位记录的错误。
    UKeyOnly: 在定位记录时使用有pfInKey标志的字段,   如果一个字段没有pfInWhere标志,将不会出现在Where子句内。
      

  12.   

    最好不要用WhereChanged,因为如果你Changed的字段如果有重复记录,可能出现更新了不该更新的记录或删除了不该删除的记录。
    我一般用的方法是用KeyOnly,然后在服务端的AfterOpen事件里将KeyField的ProviderFlags设置为pfInKey
      

  13.   

    呵, 原来 UpdateMode 都没设好...不同意鸟的说法, 我更偏好设 UpdateMode 设成 upWhereChanged, 因为这样的情况才能大量用户使用时最小发生后者的更新代替前者...同意 billy_zh(牛仔) 对 UpdateMode 的介绍补一点, pfInKey 的字段不管是 UpdateMode 中哪一种都会参与定位, 由此可以看出 upWhereChanged 一定要指定一个字段为 pfInKey, 虽然它没有强制你要这么做, 主要问题就出在改动后的字段都不能用于定位一条唯一记录时, 显然如果有个 Key 一定参与定位后这样的问题就不会存在了
      

  14.   

    大富翁的这个问答有问题啊在大富翁论坛上有人帮我解决了问题。他要我在服务端的AdoQuery的afterOpen事件里加以下代码:
    var
     i: Integer;
    begin
     for i := 0 to Dataset.FieldCount - 1 do
       if Dataset.Fields[i].CanModify then
         dataset.Fields[i].ProviderFlags := [pfInUpdate];
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     这样就没事了,所有数据都可以更新了。这样一做, 就等于了 upWhereKeyOnly为了明白我对 ProviderFlags 再作个说明
    先决条件, 你有没习惯在服务器这边的 query add all fields? 如果没有, 请一定要这么做, 这很重要, 这样就可以在设计期时就决定 ProviderFlag.pfInKey:  
      重要条件, 这个字段是唯一的主键, pfInKey 的字段是无论无何都会参与WHERE 用于定位原记录的, 而不管你设 UpdateMode 成什么, 除非以下 pfInWhere 没有出现在 ProviderFlags 中pfInWhere:
      该字段是否参与定位原记录, 这主要影响的是 UpdateMode 中 upWhereAll, 和 upWhereChanged, upWhereKeyOnly 也受影响, 但似呼不合理, 所以 pfInKey 的没理由不没pfInWhere;pfInUpdate:
      该字段是否被更新(insert or update), 一般都是要的, 显而易见的不设 InUpdate 一个例子是Query中用到多表 join 的语句, midas 是不会多表更新的(但现下 ADO可以, ResolveToDataSet), 所以你得设设
     
    pfHidden: 这个字段在客户机隐藏, 但不表示字段不在客户数据包中
      

  15.   

    to comanche(太可怕) 
      “先决条件, 你有没习惯在服务器这边的 query add all fields? 如果没有, 
      请一定要这么做, 这很重要, 这样就可以在设计期时就决定 ProviderFlag.”你这样做有很多的局限性,最突出的就是要对每个需要更新的表建立一个Dataset。to 楼主
      建议对VCL代码进行单步追踪,这样的问题有时候是因为表名称或字段名称与SQL的
      保留字相同引起的。
      

  16.   

    是的我不会在代码中加入 Query.SQL.Text = '...' 这种东东, 这样可读性太低
    我也不用 CommandText, 这样还不如用 ADO 控件写c/s来得简单总之静态 Query 好处多多, 这跟楼主的题远了...