ADO主细表更新出错,绝对难题!(200分)

  • 主题发起人 主题发起人 savetime
  • 开始时间 开始时间
S

savetime

Unregistered / Unconfirmed
GUEST, unregistred user!
ADO主细表更新出错,绝对难题!

我在设计一个ADO主细表表单时,发生以下故障,请大侠帮助!
环境:Delphi5 SP1, ADO SP1, ADO SP2, 数据库:ACCESS2000
主表: MasterDataSet (LockType: ltOptimistic)
细表: DetailDataSet (LockType: ltBatchOptimistic)
ACCESS中主细表之间已设置好一对多、级联更新、删除关联。
表单中,MasterDataSet和DetailDataSet已设置Master/Detail模式。
主表用DBEDIT等控件,细表用DBGRID控件。
在表单的保存按钮过程中,写有以下代码:
代码:
begin
  //开始事务处理
  DM.Conn.BeginTrans;
  //保存主表
  try
    if MasterDataSet.State in [dsEdit, dsInsert] then
      MasterDataSet.Post;
  except
    DM.Conn.RollbackTrans;
    raise;  //错误信息进入另一处理模块,下同
    Exit;
  end;
  //保存细表
  try
    DetailDataSet.UpdateBatch;
  except
    DM.Conn.RollbackTrans;
    raise;
    Exit;
  end;
  //提交事务
  DM.Conn.CommitTrans;
  FEditing := False;
  SetToolBarState;
end;
问题:
当编辑一个已存在的数据记录时,保存没有问题。
错误1:
当新增一条记录时,如果主表没有被POST就增加细表项,细表项在
新增第二项时先前增加的一项被删除,也就是无法增加细表项。
错误2:
如果将细表的LockType改为ltOptimistic则新增细表项的Post过程
就出现错误:“主表需要一个相关记录,不能增加或修改记录”。
注意:这是个OLE错误,通常的DELPHI数据库错误都是DATABASE类。
错误3:
如果把ACCESS中的关联删除,则同样出现错误1,但在使用以上的保
存过程后,被删除的子项又出现在DBGRID中,并已写入数据库。
初步分析:
根据以上测试,在保存过程中,主表的数据已写入数据库(虽然是在
事务中),但细表不能识别主表中记录的存在,这就很奇怪了。如果
主表的LockType也是ltBatchOptimistic,会出现什么样的情况呢?
另外,为什么错误1没有触发错误,而错误2却触发,是否说明DELPHI
没能很好地处理BatchUpdate过程。错误2中触发的OLE错误是因为
ACCESS中的关联吗?
我想这应该是DELPHI的BUG。请大家关注!
如果大家有更好的处理ADO主细表的方案,请提出。
 
begin
//开始事务处理
//保存主表
try
if MasterDataSet.State in [dsEdit, dsInsert] then
begin
DM.Conn.BeginTrans;
MasterDataSet.Post;
DM.Conn.commTrans;
end;
except
DM.Conn.RollbackTrans;
raise; //错误信息进入另一处理模块,下同
Exit;
end;
//保存细表
try
DM.Conn.BeginTrans;
DetailDataSet.UpdateBatch;
DM.Conn.commTrans;
except
DM.Conn.RollbackTrans;
abort;
end;
//提交事务
FEditing := False;
SetToolBarState;
end;
 
荷塘新月, 你这样还是不能完全控制主细表。假如细表出错,主表还是保存了。
 
荷塘新月, 刚才没说清楚,我试了一下,如果细表在主表的POST之前新增的话,
还是不能保存啊。错误依旧。
 
在Delphi中Master/Detail的处理实际上是通过设置Detail表的Filter来实现的,如果你在
新增一条主表纪录时,如果连接字段预先未赋值的话,也就是说它的Value为NULL,那么因为
Filter功能上的限制,它的子表就会是上面说的那样了。解决此问题有两种方法:
1、在master新增时就给连接字段赋值
2、不用Delphi的master/detail连接,而是自己动态的控制
一般来说,我趋向于后者,这样的话detail就可以不用一次性把所有数据都取到客户端,
效率上有提高而且控制也简单
 
这不是什么绝对难题,更不是delphi的bug:
1.主表用 ltoptimistic而从表用ltbatchoptimistic,本身就不是很好的做法,况且又加上
事务,我以前也这样做,问题不少,尤其时在多用户情况下--哦,你是用Access的,那应该是
单机版,单机版事务处理并不是很重要呀.
2,如果一定要事务,为什么主表不用batchoptimistic?
3.许多用户在输入时确实会忘了先输主表而直接输子表,那你为什么不在从表的dbgride
的onenter事件中对主表post一下?
 
在从表的dbgride的onenter事件中对主表post一下
 
1、只有子表用缓存更新方式,主表不用
2、主从表的级联关系用手工处理
3、我忘了,呵呵,
我以前也提过这个问题,你去看看吧
http://www.delphibbs.com/delphibbs/dispq.asp?lid=777037
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
898
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部