我在项目开发中遇到了一个问题,简化测试步骤如下:1: 在sql server查询分析器中,创建2个table,
CREATE TABLE TableA (no int, name varchar(10))INSERT INTO TableA
select 1, 'wp' union all
select 2, 'lj' union all
select 3, 'df' CREATE TABLE TableB (no int, name varchar(10))INSERT INTO TableB
select 4, 'tt' union all
select 5, 'as' union all
select 6, 'dc'
-----------------------------
2: 在delphi中,新开一个工程,加入几个控件,
ADOConnection1, ADOQuery1; DataSource1, DBGrid1, Button1,  Edit1
连上数据库以后.在ADOQuery1.SQL写上如下语句:
SELECT * FROM TableA
union all
SELECT * FROM TableB在Button1.Click中写上如下语句:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.Edit;
  ADOQuery1.FieldByName('name').AsString := edit1.Text;
  ADOQuery1.Post;
end;-----------
3: 我开始修改TableA union all TableB 的数据,当我修改id = [1,2,3]的时候都可以成功的把name值改过来,可是当我修改id = 4的时候,出错:
Row cannot be located for updating. some values may have been changed since it was last read一般来讲,这种错误是在2个客户端同时修改一条纪录,当一个客户端提交修改数据到数据库的以后,另一个客户端再去提交的时候,就会出这种错。
可是没有想到的是,union all 2个table的数据,修改tableA的数据没有问题,一旦修改tableB的数据就出错!!!我的程序确实需要把2个表的数据同时显示在一个DBGrid中,让用户去修改,如果这种错误存在的话, 我该应该怎幺做呀??? 非常感谢,很急!!!

解决方案 »

  1.   

    用ADOStoreProc1去做也是出一样的错! 我在项目中使用的就是ADOStoreProc1 出错的。 :)
      

  2.   

    这个机制也我也不很了解,给楼主一个简单的提示吧,
    用 临时表 去做啊,只要在前面加一个字段就行了, A 表的字段值就设置成 A ,B 表的值就设置成 B 
    这样的话当用户保存的时候一
    根据 A,B 表的标识人别用 Delete 和 Insert 插入回到 A,B 表中,
    不过这样做如果记录集比较大的时候恐怕,效率有会问题。
      

  3.   

    默认值的问题;
    因为是静态集,而ADO在形成SQL语句时,是以你第一次提出的数据字段为更新定位条件, 所以,当第一位用户修改数据库后,第二位用户的SQL语句用原来的条件就怎么也找不到原来的那一条记录了.
    办法:
    1、在新增记录时必须为每个字段赋值;
    2、直接运行SQL语句,不用ADO形成(ADOConnection1.Execute('Update......'))
      

  4.   

    具体的代码我没有测试,我想提一个问题:
    既然两个表的结构是一致的,为什么要分成两个表呢?如果一定要分成两个表,那么我想通过直接执行SQL更新是可行的也就是说在更新的时候,去判断这笔数据是属于哪个表
    然后再执行相应的更新动作