線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1482
推到 Plurk!
推到 Facebook!

有關緩沖中數據保存問題

尚未結案
比爾丐自
初階會員


發表:33
回覆:115
積分:29
註冊:2003-02-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-17 08:52:46 IP:218.17.xxx.xxx 未訂閱
首先謝謝大家,我現用DBGRID中輸入數據,當然是無數筆之後才保存,可存在一個問題,如何判斷在緩沖中的數據記錄重復性,當然我用了自動唯一字段,可我是要判斷另一個或幾個字段隻能輸入一條記錄,如何判斷輸入記錄的重復性?
比爾丐自
初階會員


發表:33
回覆:115
積分:29
註冊:2003-02-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-02-19 13:15:40 IP:218.17.xxx.xxx 未訂閱
引言: 首先謝謝大家,我現用DBGRID中輸入數據,當然是無數筆之後才保存,可存在一個問題,如何判斷在緩沖中的數據記錄重復性,當然我用了自動唯一字段,可我是要判斷另一個或幾個字段隻能輸入一條記錄,如何判斷輸入記錄的重復性?
這個問題很難嗎?沒人會嗎?或是緩沖中的數據記錄不用判斷重復性嗎?
T.J.B
版主


發表:29
回覆:532
積分:497
註冊:2002-08-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-02-19 14:03:51 IP:61.220.xxx.xxx 未訂閱
如要判斷資料的重複性 提供一個做法給你參考    用一個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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-02-19 16:11:06 IP:218.17.xxx.xxx 未訂閱
[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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-02-19 16:43:51 IP:61.219.xxx.xxx 未訂閱
引言: 首先謝謝大家,我現用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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-02-19 17:12:34 IP:61.220.xxx.xxx 未訂閱
如果照你所說想在輸入時就能做判斷 也是可以 不過會有一點操作邏輯的問題    假設在輸入時就做判斷 此時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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-02-20 08:28:38 IP:218.17.xxx.xxx 未訂閱
[/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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-02-20 08:35:35 IP:218.17.xxx.xxx 未訂閱
引言: 如果照你所說想在輸入時就能做判斷 也是可以 不過會有一點操作邏輯的問題 假設在輸入時就做判斷 此時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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-02-20 09:19:00 IP:61.220.xxx.xxx 未訂閱
用 query1.fieldbyname('***').FocusControl; 就可以定位到dbgrid裡面重複資料的某個欄位 天行健 君子當自強不息~~@.@
------
天行健
君子當自強不息~~@.@
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-02-20 10:21:56 IP:61.219.xxx.xxx 未訂閱
引言: 因我還有表頭,現對應的是表尾,所以必須要做判斷。你認為有必要嗎?
Multi-User 環境怎麼辦 ? "A" Client 與 "B" Client 不能修改同一筆"表頭"之"表尾"內容嗎 ? 個人認為, 資料之重複性應該置於數據庫端檢查( Unique Index or Trigger ), 這樣比較確實, Client端頂多只需負責,當 DB Server Raise Error 時, 指示因應對策, 如 cancel,rollback... 等等 Client端程式花了很多功夫(邏輯複雜),結果仍很難確保預期的"唯一". 只是個人一點淺見... /*
系統時間:2024-09-11 21:10:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!