ADO主明细表结构处理问题二则,300分(300分)

  • 主题发起人 主题发起人 oceanwave
  • 开始时间 开始时间
O

oceanwave

Unregistered / Unconfirmed
GUEST, unregistred user!
环境:
DELPHI6+ADO+ACCESS2000
数据库:
主表 Master
主表字段 MID
明细表 Detail
明细表字段 MID,DID
试验程序控件安排
用TADODataSet连接主表和明细表(按李维书上所示方法连接主/明细表)。
方案一:
普通模式(不打开缓存更新模式)
在主表的BeforePost中打开事务管理:
connection.BeginTrans;
在主表的AfterPost中提交事务:
connection.CommitTrans;
在主表的PostError中回滚事务:
connection.RollbackTrans;
方案二
缓存更新模式(将主表、明细表的LockType设为ltBatchOptimistic)
更改主表的AfterPost事件为
dsMaster.UpdateBatch();
dsDetail.UpdateBatch();
Connection.CommitTrans;
方案三
打上述的数据的提交过程写以一个提交的按钮事件中:
Connection.BeginTran;
try
dsMaster.UpdateBatch();
dsDetail.UpdateBatch();
Connection.CommitTrans;
except
Connection.RollbackTrans;
end;
应该说来该设置也设置,也老老实实按李维书中写的做了,但问题出现了:
问题:
1.当主表在新增状态下, 明细只会显示一个记录(明细用TDBGrid来显示),在提交后才会
全部显示出来(但前提是不采用CacheUpdate模式).
2.如上题,在CacheUpdate模式下,主表的数据提交了,但明细表的UpdateBatch并未提交
数据。
如果不采用缓存更新方式,且在数据库定义了主表与明细表的级联关系,则提交时就会
出现主表对应记录不存在的错误提示。但如果在数据库不定义这些关系,而在程序中用代
码来维护这些关系,问题就不会出现。只是代码量多了。(这就解决了第二个问题)
其实最重要的是第一个问题,大不了我不用缓存更新方式,自己用代码来维护主明细表关
系。但直接与数据库互动在单机环境下还适用,但在多层网络架构的系统中,就会增加
网络的负担,当然要用缓存更新方式。
所以,这两个问题各150分!
请各位大侠赐教!!
 
我建议你的主表用即时更新方式,而从表用缓存方式来更新!
 
方法2较好。
 
各位大侠:不管是方案一还是二或者是三,问题一都会出现,而让我止步不前的就是这个
问题一,如果有人能帮我解决这个问题一(好方法),我这三百分都给他了,问题二另开
题目给分。不,不,不,你想要多少分开口就是了,只要能解决,我这几千分都给了你。
 
想起一个方法,就是在明细表的BeforeInsert事件做如下处理:
if dsMaster.state=dsInsert then
dsMaster.Post;
这样做解决了问题一。但问题二依然没解决。而且我认为这种解决方法有点牵强。
所以请大家赐教。
 
oceanwave的方法可行
另一种方法(对方法1):
//在对明细表操作前,先提交主表当前记录,然后再操作明细表
procedure TForm1.DBGrid2Enter(Sender: TObject);//明细表
begin
if ADODataSet1.Modified then //判断主表是否修改
ADODataSet1.Post;//提交主表
end;


 
好像不行
对方法1:
当主表信息还未填完整,不能Post,怎么办?
 
可不可以先断开主从表添加后再连接(只是想法)
 
由于在数据录入窗体中,我设置了“保存”和“取消”、“关闭”按钮,当主表为编辑
状态时“保存”和“取消”按钮可用,“关闭”按钮不可用;当主表为浏览状态时“保
存”和“取消”按钮不可用,“关闭”按钮可用。所以,在子表的BeforeDelete,Beforeinsert
,BeforeEdit事件都加了dsMaster.Edit,即在子表进入编辑状态的时候,也将主表置为
编辑状态。所以我只判断了主表是否在插入状态,才去提交。而cy408兄所讲的方法,变
成在每加一条明细记录都要提交一次主表,效率就差了。因为我把主表与明细表的关联字
段不做为商业逻辑考虑,也就是MID是由系统自动生成,不能被用户所修改,这就避免了
修改关键字而引起的级联更新问题。
现在的关键是第二个问题,我希望在这都够展开大讨论,毕竟ADO是大势所趋,而在企业
管理软件中主明细表是最重要的应用之一,我想一个标准的、稳定的、高效率的代码实现
是很多人感兴趣的话题与问题。
我也会积极的寻求解决方案,并将心得体会及摸索的过程公布出来,供大家参考。
谢谢!
 
這是我一直頭疼的問題。為此我也看了很多軟件的作法﹐概括起來也不外是以下几種﹕

1 主表的數據要先填寫并post后再操作子表的數據﹐通常是有個提交的按鈕﹐或者子表insert之
前post主表。
(這種方法最簡單﹐實現也容易﹐不過操作起來不順手)
2 子表不用數據敏感Grid,改用普通的String Grid,這樣就可以隨意填寫子表數據。
等主表和子表的數據都填好后再一起提交﹐管家婆就是這樣的。優點是操作很順
手﹐缺點代碼量大。很多操作都要自己維護。
3 這種是第2種的變形﹐主要是用內存表作為主﹐從表的臨時表﹐這樣就可以隨意編輯﹐增加
都寫好再統一提交到數據庫﹐優點是可以用數據敏感的網格﹐缺點還是代碼量大。

以上三種方法的目的都是一個﹐讓主表先post,這是要得主從關系用的連接字段的值﹐因為
一般再主從結構種的連接字段一般都是自增字段(維護方便)﹐一定要post了才能得到所以
我想是不是可以把連接字段改一改﹐改成是單據編碼什么的﹐這樣就可以脫離這個限制。
(在主表post之前就知道連接字段的值﹐這樣就可以隨意增加子表數據)﹐不過會帶來數據
庫維護方面的問題

 
其实在屡次一愁莫展之后,我也构思着用手工的方法维护数据库,主表倒没问题,无非是
几个TEDIT之类的,但在明细表所用的Grid方面,我现在都采用了TDBGridEh,这个控件
超好,特别是多标题、表脚统计等功能,让我爱不释手。
但不知lqy兄是否有相应更好的类TStringGrid控件可提供?
还有明细表的数据的提交方式(是遍历提交、还是其它办法?)
多谢!
另,我想是不是可以把讨论的方向定为
一、用TDBCtrl类的控件的CacheUpdate的解决方案
二、用普通控件,用代码手工维护数据库。
请指教!
 
多谢YNTW,但在你得DEMO中,但主表在新增状态时,明细表还是只能显示一条记录。
解决了第二个问题,但第一个问题又出现了。
请指教!
 
我又运行了一下DEMO,在主DBGrid新增时,从DBGrid就自动清空了,没有出现你说的问题呀。
有点奇怪你说的第一个问题,我这没发现,主DBGrid置于新增时,从DBGrid为空,因主表还没有Post,
从表检索不到对应的外键,所以从DBGrid为空,这是很显然的。所以我有些不明白了,我们再讨论讨论。
 
YNTW兄:
我的意思是:当主表在新增状态时,从表所在的DBGRID自然清空,但新增第二个从表
记录时,先前增加的从表记录不见了,也就是DBGRID始终只显示一个从表记录。当主表
提交后,对应这个主表记录的所有从表记录才显示出来。
你试试,多插入几个从表记录就会发现了。
 
呵呵,我已经试过了呀,一次增加五六个都没出现你说的问题呀,所以才觉得奇怪,要不要我把我的DEMO打包后发给你?
 
那多谢了,我的EMAIL地址是:
i2346@sina.com
 
补充一下,我的环境是D5+ADO 2.5(中文)+ACCESS97,因为机器比较差(P166),所以没办法在D6上试验
 
DEMO收到,但问题也是如此,看来是D6的问题罗。
不过还是多谢YNTW兄。
不知还有否解决方法?
 
老兄另外找台装有D6的机器试试,或请哪位FW帮忙在D6上试试
 
后退
顶部