ADO Master/Detail 同時刪M/D,但無法刪掉D |
答題得分者是:MorganBoy
|
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
各位前輩:先謝謝大家的幫忙。小弟初學,到處碰壁。最近學用ADO作主從表格
,要同時刪除Access資料庫某表的M及D。結果弄了一個多星期,只刪 M,而
D老是刪不掉。小弟用搜詢找了好久都找不到解答。只有厚顏請各位前輩指點
迷津了。 小弟用AdoConnection1作交易,如下
DAdoQuery.Delete ; MAdoQuery.Delete ; AdoConnection1.BeginTrans ; try DAdoQuery.UpdateBatch ; MAdoQuery.UpdateBatch ; AdoConnection1.CommitTrans ; except AdoConnection1.RollBackTrans ; DAdoQuery.CancelBatch ; MAdoQuery.CancelBatch ; end ;為何只刪 M,而D老是刪不掉? 痛了我好幾個星期了。 Kevin
------
Kevin |
pillar62
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:9 回覆:324 積分:271 註冊:2002-04-15 發送簡訊給我 |
|
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
謝謝前輩,小弟這兩個表是一對一的主從關係,一個是基本資料,另一個是
帳號資料,所以D沒用迴圈處理。 小弟有用ADO的批次更新及新學的交易功能處理這個MD刪除的問題。 這兩筆MD的資料是已存在資料庫中了,所以小弟照書上講的先刪 D,再刪M,
再執行UpdateBatch寫回資料庫,結果交易也是成功。但實際到Access看,
只刪了 M,而未刪 D。 每天試到半夜,試了一個多星期,這個MasterDetail真是煩死人。再加上
ADO-BatchUpdate,小弟真是快吐血了。 為何只刪M未刪D? 還請前輩們拉小弟一把。謝謝了。 Kevin
------
Kevin |
pillar62
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:9 回覆:324 積分:271 註冊:2002-04-15 發送簡訊給我 |
|
cashxin2002
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
您好﹗ 首先﹐您將Detail對應的ADOQuery元件的Delete方法放在開始交易的方法之前﹐那此筆交易不就無作用了嗎﹖一般來講﹐在資料開始異動前﹐就應該下開始交易的方法﹐在資料結束異動后﹐再下确認交易或取消交易的方法﹒ 小弟經常使用的做法如下﹕
在Private區或Public區域宣告一個變數﹐用于記錄鍵值欄位值﹐假設鍵值欄位為字串形態﹐我們先宣告一個StrTemp字串變數﹒
在主表對應的ADOQuery元件的的BeforeDelete事件中﹐將當前筆資料的鍵值欄位值賦予StrTemp變數﹐方法如下﹕
begin StrTemp := ADOQuery1.FieldByName('鍵值欄位名稱').AsString; end;在主表對應的ADOQuery元件的AfterDelete事件中﹐在從表對應的ADOQuery元件中﹐用迴圈刪除所有鍵值欄位值相符合StrTemp變數的資料錄﹐方法如下﹕ begin ADOQuery2.Close; ADOQuery2.SQL.Text := 'Select * From 資料表名稱'; ADOQuery2.Open; While Not ADOQuery2.Eof do begin if ADOQuery2.FieldByName('鍵值欄位名稱').AsString = StrTemp then ADOQuery2.Delete; ADOQuery2.Next; end; end;如果還有問題﹐請再描述您的資料表架構﹐及貼出相關的程式碼﹐大家再幫你看看﹒ =================================
------
忻晟 |
MorganBoy
一般會員 ![]() ![]() 發表:14 回覆:75 積分:22 註冊:2003-04-30 發送簡訊給我 |
==>要同時刪除Access資料庫某表的M及D。結果弄了一個多星期,只刪 M,而
D老是刪不掉。 考慮改成
AdoConnection1.BeginTrans ; try DAdoQuery.Delete ; DAdoQuery.UpdateBatch ; MAdoQuery.Delete ; MAdoQuery.UpdateBatch ; AdoConnection1.CommitTrans ; except AdoConnection1.RollBackTrans ; DAdoQuery.CancelBatch ; MAdoQuery.CancelBatch ; end ;M.Delete及M移位後後原先被Delete的D就... 發表人 - morganboy 於 2005/05/30 12:20:47 |
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
謝謝 Pillar62 前輩的回覆。
前輩所講的『是明細直接用datasource去跟主檔作關聯嗎??如果是這樣的話,
建議你不要用這種方式,這樣的方式比較不好控制!!建議在master的
afterscroll的時候,傳sql語法給明細,讓明細將資料取出!!這樣的方式
在控制明細和主檔之間的處理會比較好做一點!!』,小弟有點不太懂。小弟
是照書上講的
1.DAdoQuery.SQL.Text := 'Select * from OrderDetail '
'Where Order_Code=:Order_Code' ;
2.DAdoQuery.DataSource:=MAdoQueryDataSource
的方式建MD關係的。 難道還有別的方式作MD嗎?小弟有點想不通。 它總是要有MD的關係才能將資料庫裏面的東西抓來處理。切斷MD,前端不是要
被 D的資料塞暴了嗎? 小弟才接觸沒多久,白天上班看老板臉色心都亂虛一把,回家往往要抱書K到
兩三點才敢去睡。現在跟作學生時的情形實在插太多了。 謝謝Pillar62前輩指點,後進感激不盡。 Kevin
------
Kevin |
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
謝謝 cashxin2002 版主的指點,這裏人情味亂夠一把,回應如此快速且
又這麼多前輩不吝賜教,小弟銘感五內。 版主講的『您將Detail對應的ADOQuery元件的Delete方法放在開始交易的方
法之前﹐那此筆交易不就無作用了嗎﹖』,版主講的是要:
AdoConnection1.BeginTrans ; try DAdoQuery.Delete ; MAdoQuery.Delete ; ...即將DAdoQuery.Delete要包在BeginTrans後面,是嗎? 那同理,AdoQuery.Post,或AdoQuery.Append等也要放在 BeginTrans後面, 是如此嗎? 順便問個有一點點相關的問題,我還有試過 DAdoQuery.DeleteRecord,但 有ErrorMsg說不允許此操作。我看Help,DeleteRecord作的事比Delete少很 多,好像比比較適合我原先的目的,當初看完Help,亂興奮一把的。誰知.. 不過,小弟對 AdoQuery.DeleteRecords是蠻有興趣的。不知是要如何使用的。 Kevin
------
Kevin |
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
cashxin2002前輩:你好。
小弟仔細將您講的看了好久,後來似乎有點懂了。版主講的
『
在主表對應的ADOQuery元件的AfterDelete事件中﹐在從表對應的ADOQuery 元件中﹐用迴圈刪除所有鍵值欄位值相符合StrTemp變數的資料錄﹐方法如下﹕ begin ADOQuery2.Close; ADOQuery2.SQL.Text := 'Select * From 資料表名稱'; ADOQuery2.Open; While Not ADOQuery2.Eof do begin if ADOQuery2.FieldByName('鍵值欄位名稱').AsString = StrTemp then ADOQuery2.Delete;』 這是用另一個 AdoQuery 來對後端資料庫作刪除,是嗎?小弟當初也有想 過試過用SQL來作新增修改刪除,及單獨殺M或單獨殺D成功的。只是考慮到 要跟交易合起來作很麻煩。小弟再仔細想想。 另外版主講的『在Private區或Public區域宣告一個變數﹐用于記錄鍵值欄 位值﹐假設鍵值欄位為字串形態﹐我們先宣告一個StrTemp字串變數﹒ 在主表對應的ADOQuery元件的的BeforeDelete事件中﹐將當前筆資料的鍵值 欄位值賦予StrTemp變數』,這個技巧,小弟要記下來。拜領了。謝謝。 Kevin
------
Kevin |
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
|
cashxin2002
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
您好﹗ 在主從表的結構中﹐我們常常會有這種方法來刪除應主表某資料錄的刪除來對從表做相對應資料錄的刪除動作﹐以保証資料的完整性﹐將其包在交易之內﹐更可對主從資料表的異動起到安全可靠的機制﹒ 您后續發表中的交易觀念是正确的﹐交易的模式就是﹕在資料異動之前先啟動交易﹐在資料異動之后儲存或放棄交易﹐以完成一次交易的正确性﹒ DeleteRecords是一種比較特殊的刪除方式﹐它适用于ADO資料集元件的BatchUpdate模式﹐當ADO資料集元件進入BatchUpdate模式時﹐其所做的任何異動只是針對從后端資料庫擷取到前端記憶體中的資料﹐當需要确認所做的異動﹐可透過UpdateBatch方法將資料錄送回到后端﹐當需要取消異動時﹐可透過CancelBatch方法來注銷最后一次UpdateBatch之后的所有異動﹐但資料的異動除了刪除之外﹐也包括新增﹐修改等等﹐而DeleteRecords的作用是只將在BatchUpdate模式中被Deleted的資料錄真正在刪除﹐而不會影響受到新增﹐修改的資料錄﹐其使用中包括一個參數﹐方法如下﹕
ADOQuery1.DeleteRecords(arAll);
//arAll﹕所有被標識Delete的資料錄
//arFiltered﹕符合過濾條件的資料錄
//arCurrent﹕當前Delete的資料錄
//arAllChapters﹕所有被影響到的Chapters(ADO Chapters) 供您參考﹗ =================================
------
忻晟 |
MorganBoy
一般會員 ![]() ![]() 發表:14 回覆:75 積分:22 註冊:2003-04-30 發送簡訊給我 |
|
MorganBoy
一般會員 ![]() ![]() 發表:14 回覆:75 積分:22 註冊:2003-04-30 發送簡訊給我 |
|
kevin2004
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |