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

如何避免資料新增時鍵值,發聲錯誤而結束程式!

尚未結案
yaoyao01tw
一般會員


發表:28
回覆:17
積分:9
註冊:2003-01-28

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-10-15 10:49:25 IP:61.58.xxx.xxx 未訂閱
try self.ADOTable1.Insert; self.ADOTable1['廠商編號'] := self.DBGrid1.Columns[0].Field.Value; self.ADOTable1['日期'] := self.DBGrid1.Columns[1].Field.Value; self.ADOTable1.Post; finally self.AdoTable1.Cancel; Abort; end;
cashxin2002
版主


發表:231
回覆:2555
積分:1937
註冊:2003-03-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-10-15 18:17:00 IP:202.62.xxx.xxx 未訂閱
您好﹗    比較規範的做法是在資料存入之前﹐我們就應該先對資料庫進行查詢判斷是否出現鍵值重覆的現象﹐相關的做法請參考如下連接﹕ http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44779    在您的程式中﹐如果不使用上述的做法﹐也可使用攔截錯誤的方法﹐在Except中處理﹐以免引起系統的錯誤﹐如下﹕
begin
  Try
    self.ADOTable1.Insert;
    self.ADOTable1['廠商編號'] := self.DBGrid1.Columns[0].Field.Value;
    self.ADOTable1['日期'] := self.DBGrid1.Columns[1].Field.Value;
    self.ADOTable1.Post;
  Except
    On E: Exception do
    ShowMessage('出現的錯誤信息為﹕' + #10#13 + E.Message);
  end;
end;
================================= 有空來瞅瞅我﹗因為我是您的朋友﹐有您真好﹗ ================================
------
忻晟
Arlung Miao
初階會員


發表:9
回覆:44
積分:25
註冊:2004-08-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-10-16 05:20:14 IP:219.134.xxx.xxx 未訂閱
尊敬的版主cashxin2002,我要反駁你的其中一個觀點,還請見諒。 你在 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44779 提到的解決方法(在資料存入之前﹐我們就應該先對資料庫進行查詢判斷是否出現鍵值重覆的現象)並不安全。原因在於:    當你在查看鍵值時,系統(database)並未對整個Table加上一個較高級別的鎖。所以,這時候,其他用戶的執行序完全可以向表中插入同樣鍵值的一筆資料。這樣,當原來的程式再執行到更新的那段代碼時,就會有Exception出現,而系統並未攔截到(你可以做實驗,就是將你的程式在Debug模式下停在查詢代碼之後,這時另外一個程式插入一條相同鍵值的記錄。之後,你繼續執行被暫停的程式,就會有錯誤產生)。    就算你人爲的加上一把Table級的鎖,那麽從並發性的角度來看也並不可取    
   Select  From ...  //從表中檢索鍵值
   Insert ...                    //其它用戶在這裡插入相同新鍵值
   if ...Then...                        //判斷是否有重復鍵值
   Insert ...                    //或者其它用戶在這裡插入新鍵值
   Insert ...                    //插入新鍵值是產生Exception.
所以,比較可取的方法還是你提出的以下方法: begin Try self.ADOTable1.Insert; self.ADOTable1['廠商編號'] := self.DBGrid1.Columns[0].Field.Value; self.ADOTable1['日期'] := self.DBGrid1.Columns[1].Field.Value; self.ADOTable1.Post; Except On E: Exception do ShowMessage('出現的錯誤信息為﹕' #10#13 E.Message); end; end;
cashxin2002
版主


發表:231
回覆:2555
積分:1937
註冊:2003-03-28

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-10-16 09:48:16 IP:202.62.xxx.xxx 未訂閱
引言: 尊敬的版主cashxin2002,我要反駁你的其中一個觀點,還請見諒
Arlung Miao兄﹕ 能得以前輩們的指正和授教﹐小弟求之不得﹐感激不盡﹐何來見諒之意﹐呵呵﹒ 就這個問題﹐小弟覺得單對個人資料庫使用者而言﹐應該可行﹐對于多使用者的操作環境﹐小弟會找時間再測測看﹒ 如兄所述﹐如果是在多使用者的操作環境中﹐對于防止資料重覆事宜﹐能否指點建議方法途徑﹐宜于小弟的修正改進﹒謝謝﹗ ================================= 有空來瞅瞅我﹗因為我是您的朋友﹐有您真好﹗ ================================
------
忻晟
yaoyao01tw
一般會員


發表:28
回覆:17
積分:9
註冊:2003-01-28

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-10-16 10:44:40 IP:61.58.xxx.xxx 未訂閱
經實際操作,若鍵值重複還是會導致程式中斷,不知道要怎麼辦才好?    
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-10-16 11:08:39 IP:61.71.xxx.xxx 未訂閱
引言: 經實際操作,若鍵值重複還是會導致程式中斷,不知道要怎麼辦才好?
嗨! 提供一些我的意見 對於在異動回存時發生不可預期的錯誤, 有一些是可以透過 exception來解決回復, 但有些卻是無效的, 依本例就是後者, 因為你是在下post, 指令已回送後端執行結果, 而後端執行結果已發生嚴重錯誤(primary key duplicate), 對於資料庫而言, 已是結論, 除非你cancel掉重新append, 否則無法令其再運作, 所以對於資料鍵值的重覆檢查必須在你的post前就必須完成檢核 而一般資料庫設定primary key是必須很慎重的, 為避免這類問題發生(如你所提多人使用時), 我們通常不會拿可能會重覆的值做為primary key field, 例如可以自定的客戶編號, 因為這風險太高, 我的做法是primary key一定由電腦產生一個唯一性的序號, 這樣不論那一個使用者新增時, 都不會造成鍵值重覆的問題, 至於如何得知這個客戶序號是否已建立, 那就是在客戶序號的onexit欄位去攔截輸入的序號是否已存在database, 但這還是不夠, 如果今天兩位使用者同時建立了相同的序號, A,B君同時輸入, 當時的資料庫都沒有該序號, 所以回應A,B都是OK的, 此時A君先存入, 所以我在儲存前再檢查一次, 因為B君在執行儲存時還會被這段程式所攔截, 而不進行POST, 如此就可以解決重覆的問題! 或許有人要問, 為何要做兩次檢查, 其實最重要的一次是在儲存前要做, 而在客戶序號那段做的原因是因為我不希望使用者全部都輸入完畢後在儲存時才發生序號重覆的問題, 那是有風險性的存在, 一個不小心可能這筆心血全部白費, 所以才會在輸入序號後立即告知, 因為畢竟同時兩位以上要輸入重覆編號的情況並不常見(除非作業流程上規劃不當)
Arlung Miao
初階會員


發表:9
回覆:44
積分:25
註冊:2004-08-25

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-10-16 15:26:05 IP:202.103.xxx.xxx 未訂閱
老兄,實際上錯誤已經被Try語句捕捉到了。只是你們沒有關閉Debugger Options.Language Exceptions.Stop On Delphi Exceptions 選項開關,造成系統同樣給出提示信息。    請參照以下做法,關閉此開關:    
系統時間:2024-05-12 11:28:06
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!