t_1 (a1,b1)t_2(a2,b2)adoquery1.close;  adoquery1.sql.clear;
adoquery1.sql.add('select * from t_1');
adoquery1.open;
在delphi中,我一执行adoquery1.delete
就出现 无法更新定位行.一些值在最后读取的时候已更改就我一个人 操作该记录.后来我发现是因为
我在t_1中建立一个delete的触发器, 触发器的内容是:
删除t_1中记录的时候,就在t_2中删除a2=t1.a1的记录我用 adoquery1.delete 就会出现 无法更新定位行.一些值在最后读取的时候已更改 的错误
(后来,我把触发器删掉了,就正常了)
  
我用 adoquery1.close;  adoquery1.sql.clear;
    adoquery1.sql.add('delete t_1 where a1='+QuotedStr('abc'));
    adoquery1.ExecSQL;
这样是正常,也可以执行触发器的内容.能不能  用adoquery1.delete,不会出错,并且执行触发器的内容???
?????????????????????

解决方案 »

  1.   

    下面这些资料是在网上搜集的.你可参考一下:
    ============================================================在Delphi 7中,用ADOQuery或ADODataSet操作数据库很方便,可查询,可增删改。但如果对数据进行修改保存,然后再次对其进行修改保存,就会遇到“无法为更新定位行,一些值可能已在最后一次读取后已更改”的问题。原因有这样几种:1.在数据库设计时,为某些字段设置了默认值,在修改进行提交以后,数据库会自动修改对应字段的所有行的默认值,从而导致了数据库与数据集中数据的不一致,使ADOQuery(adoDataSet)无法对数据集进行定位。2.数据库对应的表没有主键,输入了重复的数据以后,数据库里有两条一样的数据,从而使ADOQuery无法对数据进行定位。解决方法:1.修改数据库设计,不再设置默认值,为数据库表定义主键,保证其唯一性。2.在执行完ADOQuery.Post之后,执行ADOQuery.Refresh,对于设置默认值的情况可以解决。
    (refresh后dataset中的默认值字段获得了值,跟数据库中一致了)3.改用Insert into sql语句插入,而不是add--post方式. 但这种方式不更新其他打开该表的query, 所以要requery才行, refresh不起作用.4.使用ADODataSet也是同样的解决方法
      

  2.   

    1.一定要为表定义一个主键ID字段,类型为自增型整数,并设为主键;
    2.共享表时,一个用户改了某记录,而另一个用户也同时改了某记录,
     后一个用户存记录时,就会出现楼主的提示,解决办法:
       将ADODataSet1的CursorLocate设为UseServer,
       
                      CursorType 设为Keyset,
     多个客户改同一条记录就不会有冲突,各改各的字段,改同一字段,最后一个人有效,
    但这种方式的表不能做从表,只能做主表;
      

  3.   

    触发器create ... on t_1
    for delete
    as
    begin
      declare @a varchar(20)
      
       定义游标cursor1
       (select aa from deleted)
      
       cursor1没到尾
          fetcht next into @a
        delete t_2 where a2=@a
      
    end 
    触发器的大概内容就是这样  根据t_1删除的a1的值来删除t_2的记录我试了一下,只要t_1和t_2都设置主键就不会有错误
    只设置t_1的主键 也会错我不明白的地方就是,为什么adoquery1.delete,会跟触发器有联系?????
    (因为没写触发器的时候,就正常)
    t_1删除一条记录后,sql 2k应该自动执行触发器的内容,跟adoquery1应该没有关系的??????