bestlong 怕失憶論壇
標題:
撰寫 Master-detail 資料表關聯時的注意事項
[打印本頁]
作者:
bestlong
時間:
2007-3-7 10:07
標題:
撰寫 Master-detail 資料表關聯時的注意事項
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), 應尋求其他的方法解決。
作者:
bestlong
時間:
2010-8-25 12:27
此篇可以作為學習參考但是邏輯上並不完整
主從表結構 ADODataSet 的 UpdateBatch 問題
看過好多主從數據表更新保存的操作,都不能解決我遇到的問題,問題是這樣的:
主從表結構,設置兩個表的
CursorType: ctKeyset,
CursorLocation: clUseClient,
LockType: ltBatchOptimistic
然後用 MasterField 關聯起來兩表,在新增一個單據時,主表輸入數據,從表輸入數據,當保存時,原來我的保存是這樣的:
if not DM.ADOConnection1.InTransaction then
begin
DM.ADOConnection1.BeginTrans;
try
ItemDataSet.UpdateBatch;
MasterDataSet.UpdateBatch;
DM.ADOConnection1.CommitTrans;
except
DM.ADOConnection1.RollbackTrans;
Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_iconwarning);
end;
end
else
begin
Application.MessageBox('服務器忙請稍後再試!',p_msgTitle,MB_OK + MB_iconWarning);
end;
複製代碼
在這種情況下,如果從表保存失敗,最常見的問題是從表有重複的記錄,那麼就會出錯,然後刪掉重複的記錄回來,再保存,不會有什麼問題,然而,實際上從表的數據根本就沒有保存進去,而僅僅成功保存的是主表的數據。
原因是:因為在從表UpdateBatch之前,系統默認調用Post,這樣就從表就不能返回到以前的狀態,所以不能更新,而在UpdateBatch之前遍歷從表數據,找出重複的記錄刪除掉,我覺得代碼上比較麻煩,所以我就想,既然系統默認調用Post,我何不手工調用Post,捕捉錯誤,然後處理掉這個錯誤,再回來保存,那不就有可能成功嗎?於是就有了下面這段代碼:
try
ItemDataSet.Post; //保存之前先Post,如果出錯,則不保存,置於編輯狀態
ItemDataSet.UpdateBatch;
MasterDataSet.Post;
MasterDataSet.Edit;
ItemDataSet.Edit;
except
Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_IconWarning);
MasterDataSet.Edit;
ItemDataSet.Edit;
Abort;
end;
if not DM.ADOConnection1.InTransaction then
begin
DM.ADOConnection1.BeginTrans;
try
ItemDataSet.UpdateBatch;
MasterDataSet.UpdateBatch;
DM.ADOConnection1.CommitTrans;
except
DM.ADOConnection1.RollbackTrans;
Application.MessageBox('數據保存失敗!請檢查編碼是否重複。',p_msgTitle,MB_OK + MB_IconWarning);
end;
end
else
begin
Application.MessageBox('服務器忙請稍後再試!',p_msgTitle,MB_OK + MB_IconWarning);
end;
複製代碼
保存,運行,果然,成功了!
資料來源
http://www.8888i.net/dispQAInfo.php?id=1196
歡迎光臨 bestlong 怕失憶論壇 (http://www.bestlong.idv.tw/)
Powered by Discuz! X1.5