bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 撰寫 Master-detail 資料表關聯時的注意事項 ...
查看: 6808|回復: 1
go

撰寫 Master-detail 資料表關聯時的注意事項 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2007-3-7 10:07 |只看該作者 |倒序瀏覽 |打印
1. 如果資料庫本身不支援 Cascading delete, 自己要記得做。

2. 如果 Master table 的 Key Field 是採用電腦自動編號, 應使用程式自動編號, 而不要依賴資料庫的 AutoInc 形態的欄位。

3. Master table 的 Key Field 應該是儲存以後就不能修改, (否則 Detail table 將失去關連)

4. 當 Master table 新增一筆資料時, 必須先將這筆資料儲存之後才允許新增 Detail 細項, 以免在網路多人環境下易造成 Key Violation.

5. Master table 經常會有一個 (以上) 的加總欄位, 其值是 Detail table 某欄位的總和, 欲實作此欄位, 必須在每次 Detail table 的 AfterPost 之後自行加總, 再將總和丟給 Master table. 加總的方法: 可利用一迴圈或是一個 TQuery, 若為 server based 資料庫, 可利用 trigger 為之 (每當 Detail table 有 Insert 或 Update 等動作時就重新加總。

6. DisableControls 會切斷 Table 與 DataSource 之間的連接, 而 Detail Table 是透過 MasterSource 屬性來取得資料, 所以在處理 Master-Detail Table 時不可使用 DisableControls. 如果要加快顯示速度 (例如: TDBGrid), 應尋求其他的方法解決。
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw

Rank: 9Rank: 9Rank: 9

2#
發表於 2010-8-25 12:27 |只看該作者
此篇可以作為學習參考但是邏輯上並不完整

主從表結構 ADODataSet 的 UpdateBatch 問題

看過好多主從數據表更新保存的操作,都不能解決我遇到的問題,問題是這樣的:
主從表結構,設置兩個表的

CursorType: ctKeyset,
CursorLocation: clUseClient,
LockType: ltBatchOptimistic

然後用 MasterField 關聯起來兩表,在新增一個單據時,主表輸入數據,從表輸入數據,當保存時,原來我的保存是這樣的:
  1. if not DM.ADOConnection1.InTransaction then
  2. begin
  3.   DM.ADOConnection1.BeginTrans;
  4.   try
  5.     ItemDataSet.UpdateBatch;
  6.     MasterDataSet.UpdateBatch;
  7.     DM.ADOConnection1.CommitTrans;
  8.   except
  9.     DM.ADOConnection1.RollbackTrans;
  10.     Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_iconwarning);
  11.   end;
  12. end
  13. else
  14. begin
  15.   Application.MessageBox('服務器忙請稍後再試!',p_msgTitle,MB_OK + MB_iconWarning);
  16. end;
複製代碼
在這種情況下,如果從表保存失敗,最常見的問題是從表有重複的記錄,那麼就會出錯,然後刪掉重複的記錄回來,再保存,不會有什麼問題,然而,實際上從表的數據根本就沒有保存進去,而僅僅成功保存的是主表的數據。

原因是:因為在從表UpdateBatch之前,系統默認調用Post,這樣就從表就不能返回到以前的狀態,所以不能更新,而在UpdateBatch之前遍歷從表數據,找出重複的記錄刪除掉,我覺得代碼上比較麻煩,所以我就想,既然系統默認調用Post,我何不手工調用Post,捕捉錯誤,然後處理掉這個錯誤,再回來保存,那不就有可能成功嗎?於是就有了下面這段代碼:
  1. try
  2.   ItemDataSet.Post;   //保存之前先Post,如果出錯,則不保存,置於編輯狀態
  3.   ItemDataSet.UpdateBatch;
  4.   MasterDataSet.Post;
  5.   MasterDataSet.Edit;
  6.   ItemDataSet.Edit;
  7. except
  8.   Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_IconWarning);
  9.   MasterDataSet.Edit;
  10.   ItemDataSet.Edit;
  11.   Abort;
  12. end;

  13. if not DM.ADOConnection1.InTransaction then
  14. begin
  15.   DM.ADOConnection1.BeginTrans;
  16.   try
  17.     ItemDataSet.UpdateBatch;
  18.     MasterDataSet.UpdateBatch;
  19.     DM.ADOConnection1.CommitTrans;
  20.   except
  21.     DM.ADOConnection1.RollbackTrans;
  22.     Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_IconWarning);
  23.   end;
  24. end
  25. else
  26. begin
  27.   Application.MessageBox('服務器忙請稍後再試!',p_msgTitle,MB_OK + MB_IconWarning);
  28. end;
複製代碼
保存,運行,果然,成功了!

資料來源 http://www.8888i.net/dispQAInfo.php?id=1196
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-5-17 11:25 , Processed in 0.011651 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.