有關緩沖中數據保存問題 |
尚未結案
|
比爾丐自
初階會員 ![]() ![]() 發表:33 回覆:115 積分:29 註冊:2003-02-14 發送簡訊給我 |
|
比爾丐自
初階會員 ![]() ![]() 發表:33 回覆:115 積分:29 註冊:2003-02-14 發送簡訊給我 |
|
T.J.B
版主 ![]() ![]() ![]() ![]() ![]() 發表:29 回覆:532 積分:497 註冊:2002-08-14 發送簡訊給我 |
如要判斷資料的重複性 提供一個做法給你參考 用一個temptable
然後
用來檢查dbgrid的query(假設為querydbgrid)
temptable.open; <--用來檢查 querydbgrid.open; <---連結dbgrid的query querydbgrid.first; while not querydbgrid.eof do begin s1: querydbgrid.fieldbyName('empno').asstring;//<--用來檢查是否重複的key值 if not (temptable.locate('empno',s1,[])) then //用s1去找query的key值 begin temptable.append; temptable.FieldByName('empno').AsString := s1; // 做存檔動作 temptable.post; end else begin Application.MessageBox('資料重複!!請查明','訊息視窗',MB_ICONERROR); exit; end; querydbgrid.next; end;ps:temptable的欄位不需要跟dbgrid的欄位一樣多 因為它只是用來檢查資料是否重複(也就是檢查key值) 所以querydbgrid的key值有幾個 temptable的欄位就跟key值的數目一樣即可 天行健 君子當自強不息~~@.@ 發表人 - T.J.B 於 2003/02/19 14:15:55 發表人 - T.J.B 於 2003/02/19 14:18:28
------
天行健 君子當自強不息~~@.@ |
比爾丐自
初階會員 ![]() ![]() 發表:33 回覆:115 積分:29 註冊:2003-02-14 發送簡訊給我 |
[quote]
如要判斷資料的重複性 提供一個做法給你參考 用一個temptable
然後
用來檢查dbgrid的query(假設為querydbgrid)
temptable.open; <--用來檢查 querydbgrid.open; <---連結dbgrid的query querydbgrid.first; while not querydbgrid.eof do begin s1: querydbgrid.fieldbyName('empno').asstring;//<--用來檢查是否重複的key值 if not (temptable.locate('empno',s1,[])) then //用s1去找query的key值 begin temptable.append; temptable.FieldByName('empno').AsString := s1; // 做存檔動作 temptable.post; end else begin Application.MessageBox('資料重複!!請查明','訊息視窗',MB_ICONERROR); exit; end; querydbgrid.next; end;ps:temptable的欄位不需要跟dbgrid的欄位一樣多 因為它只是用來檢查資料是否重複(也就是檢查key值) 所以querydbgrid的key值有幾個 temptable的欄位就跟key值的數目一樣即可 謝謝你,我明白,不過隻能在最後保存提交記錄時才能這樣做嗎?不能在輸入的控件DBGRID中當輸入一條記錄時就判斷嗎?如能,就用這種方法也許可以,不過當輸入一條時當移動時就做保存到另一個temptable,但刪除了因還未提交時做刪除動作,這時就不好處理temptable剛才做的保存的那條記錄.你說呢?因我很想在輸入時就能做判斷! |
Mickey
版主 ![]() ![]() ![]() ![]() ![]() 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
引言: 首先謝謝大家,我現用DBGRID中輸入數據,當然是無數筆之後才保存,可存在一個問題,如何判斷在緩沖中的數據記錄重復性,當然我用了自動唯一字段,可我是要判斷另一個或幾個字段隻能輸入一條記錄,如何判斷輸入記錄的重復性?1. 除非 DBGrid.DataSource.DetaSet is Table 判斷輸入記錄的重復性才有意 義, 如果是 Query, 只取得 id=2 之 record ( select ... where id=2 ), 事實上 DataBase Server 中 id=1 之 record 亦存在, 如此的情況下, 判斷輸入記錄的重復性, 只是 Check Client-Side Data ? 只有於 DB Server Create Unique Index 一途. 2. 如果是Table ,而且你運用 DataSetProvider->ClientDataSet->DataSource->DBGrid, 這樣的機構, Check Unique Eaxmple Code 如下(看起來有點笨,但因 ClientDataSet.Data係Memory運算,速度很快): procedure TForm1.ClientDataSet1BeforeApplyUpdates(Sender: TObject; var OwnerData: OleVariant); var TempCD:TClientDataSet; k : string; //Temp KeyValue begin TempCD := TClientDataSet.Create(Self); ClientDataSet1.DisableControls; try TempCD.CloneCursor(ClientDataSet1, True); TempCD.Filtered := True; ClientDataSet1.First; while not ClientDataSet1.Eof do begin k := ClientDataSet1.Fields[0].AsString; TempCD.Filter := 'C1='#39 k #39; if TempCD.RecordCount>1 then begin ClientDataSet1.CancelUpdates; raise Exception.Create('Duplicate Key Found !'); end; ClientDataSet1.Next; end; finally ClientDataSet1.EnableControls; TempCD.Free; end; end;/* Free 和 Create 一樣重要 */ |
T.J.B
版主 ![]() ![]() ![]() ![]() ![]() 發表:29 回覆:532 積分:497 註冊:2002-08-14 發送簡訊給我 |
如果照你所說想在輸入時就能做判斷 也是可以
不過會有一點操作邏輯的問題 假設在輸入時就做判斷 此時query的狀態是在insert mode 或 edit mode
且是把資料先放在暫存區(也就是緩沖區中)
直到ApplyUpdates才寫回資料庫
但此時user可能未全部輸入資料完畢
就做取消的動作 此時query的狀態回到brower mode
而且暫存區(也就是緩沖區中)的資料全部清空
那麼在輸入時就做判斷就變的毫無意義
與其如此 到不如等user 做存檔時再做檢查會比較好 另外 你提到的一點
不過當輸入一條時當移動時就做保存到另一個temptable,但刪除了因還未提交時做刪除動作,這時就不好處理temptable剛才做的保存的那條記錄. 注意 : 此時的資料是放在暫存區(也就是緩沖區中)
因為此時query的狀態是在insert mode 或 edit mode
所以user是無法對暫存區(也就是緩沖區中)的資料做刪除的動作
只能做cancel或ApplyUpdates的動作
所以不必擔心不好處理temptable剛才做的保存的那條記錄
因為當user做cancel的動作時 把temptable的資料清空即可
而user又重新輸入時 再把它記錄到temptable 總結 :
1:最好是在存檔時去檢查
2:真要在輸入時就能做判斷也可以 ,
但要考慮user做cancel時記的把temptable的資料清空
為什麼無法做也不可做刪除動作 原因如上
3: 存檔完畢也要把temptable的資料清空 天行健
君子當自強不息~~@.@
------
天行健 君子當自強不息~~@.@ |
比爾丐自
初階會員 ![]() ![]() 發表:33 回覆:115 積分:29 註冊:2003-02-14 發送簡訊給我 |
[/quote]
1. 除非 DBGrid.DataSource.DetaSet is Table 判斷輸入記錄的重復性才有意
義, 如果是 Query, 只取得 id=2 之 record ( select ... where id=2 ),
事實上 DataBase Server 中 id=1 之 record 亦存在, 如此的情況下,
判斷輸入記錄的重復性, 只是 Check Client-Side Data ?
只有於 DB Server Create Unique Index 一途.
2. 如果是Table ,而且你運用 DataSetProvider->ClientDataSet->DataSource->DBGrid,
這樣的機構, Check Unique Eaxmple Code 如下(看起來有點笨,但因 ClientDataSet.Data係Memory運算,速度很快):
procedure TForm1.ClientDataSet1BeforeApplyUpdates(Sender: TObject; var OwnerData: OleVariant); var TempCD:TClientDataSet; k : string; //Temp KeyValue begin TempCD := TClientDataSet.Create(Self); ClientDataSet1.DisableControls; try TempCD.CloneCursor(ClientDataSet1, True); TempCD.Filtered := True; ClientDataSet1.First; while not ClientDataSet1.Eof do begin k := ClientDataSet1.Fields[0].AsString; TempCD.Filter := 'C1='#39 k #39; if TempCD.RecordCount>1 then begin ClientDataSet1.CancelUpdates; raise Exception.Create('Duplicate Key Found !'); end; ClientDataSet1.Next; end; finally ClientDataSet1.EnableControls; TempCD.Free; end; end;/* Free 和 Create 一樣重要 */ [/quote] 多謝,你的這種辦法也好,不過第二種辦法隻能對表,且要是用DataSetProvider->ClientDataSet->這樣的機構才行, 我現用二層暫時考慮不能用此結構,包括你前天回答的我另一個問題,我現隻能理解用此結構才能很好的控制我要保存的資料,也就是能控制好ADO引擎問題,也許不全對. 對於第一種 如果是 Query, 只取得 id=2 之 record ( select ... where id=2 ), 事實上 DataBase Server 中 id=1 之 record 亦存在, 如此的情況下, 判斷輸入記錄的重復性, 只是 Check Client-Side Data ? 我不能理解,因一般我都是用Query新增修改資料的,id是不是自動唯一號,如果是就不能用它來判斷,因我本來就有唯一號的,且是自動取號的,這樣它永遠不會有重復的記錄從在,但現要用另一個或兩個字段做為判斷重復的,但它有不能做為在數據庫中就設為唯一性的。因我還有表頭,現對應的是表尾,所以必須要做判斷。你認為有必要嗎? |
比爾丐自
初階會員 ![]() ![]() 發表:33 回覆:115 積分:29 註冊:2003-02-14 發送簡訊給我 |
引言: 如果照你所說想在輸入時就能做判斷 也是可以 不過會有一點操作邏輯的問題 假設在輸入時就做判斷 此時query的狀態是在insert mode 或 edit mode 且是把資料先放在暫存區(也就是緩沖區中) 直到ApplyUpdates才寫回資料庫 但此時user可能未全部輸入資料完畢 就做取消的動作 此時query的狀態回到brower mode 而且暫存區(也就是緩沖區中)的資料全部清空 那麼在輸入時就做判斷就變的毫無意義 與其如此 到不如等user 做存檔時再做檢查會比較好 另外 你提到的一點 不過當輸入一條時當移動時就做保存到另一個temptable,但刪除了因還未提交時做刪除動作,這時就不好處理temptable剛才做的保存的那條記錄. 注意 : 此時的資料是放在暫存區(也就是緩沖區中) 因為此時query的狀態是在insert mode 或 edit mode 所以user是無法對暫存區(也就是緩沖區中)的資料做刪除的動作 只能做cancel或ApplyUpdates的動作 所以不必擔心不好處理temptable剛才做的保存的那條記錄 因為當user做cancel的動作時 把temptable的資料清空即可 而user又重新輸入時 再把它記錄到temptable 總結 : 1:最好是在存檔時去檢查 2:真要在輸入時就能做判斷也可以 , 但要考慮user做cancel時記的把temptable的資料清空 為什麼無法做也不可做刪除動作 原因如上 3: 存檔完畢也要把temptable的資料清空 天行健 君子當自強不息~~@.@當在保存時才做判斷,如果有重復的記錄存在,那如何定位到DBGRID中相應的記錄上呢?因如果記錄很多的話,要去看重復的記錄是件不很容易的事情,當然我可以提示關鍵的那個字段的信息已重復。你有沒有更好的辦法一檢查有能馬上定位? |
T.J.B
版主 ![]() ![]() ![]() ![]() ![]() 發表:29 回覆:532 積分:497 註冊:2002-08-14 發送簡訊給我 |
|
Mickey
版主 ![]() ![]() ![]() ![]() ![]() 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
引言: 因我還有表頭,現對應的是表尾,所以必須要做判斷。你認為有必要嗎?Multi-User 環境怎麼辦 ? "A" Client 與 "B" Client 不能修改同一筆"表頭"之"表尾"內容嗎 ? 個人認為, 資料之重複性應該置於數據庫端檢查( Unique Index or Trigger ), 這樣比較確實, Client端頂多只需負責,當 DB Server Raise Error 時, 指示因應對策, 如 cancel,rollback... 等等 Client端程式花了很多功夫(邏輯複雜),結果仍很難確保預期的"唯一". 只是個人一點淺見... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |