全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1040
推到 Plurk!
推到 Facebook!

要怎麼樣在錯誤發生時讓程式自動執行下去

尚未結案
dino
一般會員


發表:20
回覆:73
積分:23
註冊:2002-07-29

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-06 12:23:39 IP:61.219.xxx.xxx 未訂閱
資料庫:SQL Server 2000 Enterprise Edition
while not DBGrid1.DataSource.DataSet.Eof do
     begin
        ADOConnection1.BeginTrans;
        try
            dest_Query.Insert;
            dest_Query.FieldByName('CARGO_IN_NO').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_IN_NO').Value;
            dest_Query.FieldByName('CARGO_IN_SN').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_IN_SN').Value;
            ...
            dest_Query.FieldByName('RECEIVE_AREA').Value := DBGrid1.DataSource.DataSet.FieldByName('RECEIVE_AREA').Value;
            dest_Query.FieldByName('CARGO_SUM').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_SUM').Value;
            dest_Query.Post;
            source_Query.Delete;
            Application.ProcessMessages;
            ADOConnection1.CommitTrans;
        except
            on E:Exception do
            begin
              ADOConnection1.RollbackTrans;
              if Pos('Attempt to insert duplicate key row',E.Message)>0 then //假設當資料重複時資料庫回傳的錯誤訊息有以上字串....
                 raise Exception.Create('新增的資料已經存在')
              else
                 raise Exception.Create('資料儲存失敗,錯誤訊息如下:'#13 E.message);
              exit;
            end;
        end;
     end;
以上的程式碼是將A table的資料一筆一筆insert到B table之後再delete 如果發生意外中斷時,下次執行時就會引發資料已經重複的訊息,我想應該是 ADOConnection1.RollbackTrans;這行的關係吧,我猜想Rollback回來的應該是出問題的時候正在處理的那一筆資料,所以每次強迫中斷程式後再Run時都會有一筆重複,如果我想的沒錯的話,是不是中斷過後再Run時,B table有遇到A table相同的資料時可以先delete掉,再從A table insert過來,亦或是不要用Rollback(但是一定有什麼風險...我想),還是先delet A table的第一筆資料(我想重複都是發生在一開始的那一筆吧?),所以我的問題是在try...except 發生重複的問題時,except...end要怎麼處理, 而且處理完畢後會回到try...except中繼續insert的動作而不會中斷 不曉得會不會說的很籠統,希望各位先進可以看的懂才好 謝謝
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-06 19:12:14 IP:220.132.xxx.xxx 未訂閱
基本上這個問題好解決, 若是只是要判定是否是有重覆資料, 有則先刪除再加入的話, 可以這麼做,    1. 先利用另一個 ADOQuery 下 command check是否目地 table 已存在資料, 如, 
tmp_Query.SQL.Text := 'select * from TABLEB where primary_key = .... ';
tmp_Query.Open;
if not tmp_Query.eof then
begin
  tmp_Query.Close;
  tmp_Query.SQL.Text := 'delete from TABLEB where primary_key = ... ';
  tmp_Query.ExecSQL;
end;
2. 接下來就可以進行你要操作的過程囉!!
dino
一般會員


發表:20
回覆:73
積分:23
註冊:2002-07-29

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-07 16:51:24 IP:61.219.xxx.xxx 未訂閱
sorry 小弟愚昧 不懂要怎麼做 假設table是以a, b, c這三個欄位組成唯一值 那我要怎麼寫呢 primary key=?? primary key是寫成a,b,c嗎?等於什麼呢? 這個程式是把A 資料庫的X table insert到B 資料庫的X table(兩個是一模一樣的) 順便請教一個SQL語法 ,我要怎麼樣把B 資料庫的X table裡面有重複出現於A 資料庫的X table的資料select出來呢?
likush
高階會員


發表:5
回覆:235
積分:103
註冊:2002-10-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-07 21:13:14 IP:220.134.xxx.xxx 未訂閱
query1.close;
query1.sql.add('select fielda from table1 where fielda=''' edit1.text '''... ');
query1.open;
if not query1.isempty then
begin
 query2.close;
 query2.sql.add('insert.....');
 query2.ExecSQL;
end;
先判斷是否有重覆資料存在,如果沒有則進行新增,如有則依你的作法來作 以SQL語法來來取出二個table的重覆資料可以 select field1, field2 from table1 where field1 in (select field1 from table2) ========================= 讀萬卷書~不如來K.TOP走一遭 =========================
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-07 22:10:51 IP:218.169.xxx.xxx 未訂閱
hi,dino: 底下不曉得是不是你要的,把insert錯誤的資料存入TStringList裡,如下:
var
  ss:TStringList;
  i:Integer;
  str:String;
begin
  ss:=TStringList.Create;
  while not DBGrid1.DataSource.DataSet.Eof do
  begin
    ADOConnection1.BeginTrans;
    try
        dest_Query.Insert;
        dest_Query.FieldByName('CARGO_IN_NO').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_IN_NO').Value;
        dest_Query.FieldByName('CARGO_IN_SN').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_IN_SN').Value;
        ...
        dest_Query.FieldByName('RECEIVE_AREA').Value := DBGrid1.DataSource.DataSet.FieldByName('RECEIVE_AREA').Value;
        dest_Query.FieldByName('CARGO_SUM').Value := DBGrid1.DataSource.DataSet.FieldByName('CARGO_SUM').Value;
        dest_Query.Post;
        source_Query.Delete;
        Application.ProcessMessages;
        ADOConnection1.CommitTrans;
    except
      on E:Exception do
      begin
        ADOConnection1.RollbackTrans;
        str:=DBGrid1.DataSource.DataSet.Fields[0].AsString;
        for i:=1 to DBGrid1.DataSource.DataSet.FieldCount-1 do
          str:=str+'@'+DBGrid1.DataSource.DataSet.Fields[i].AsString;  //以@做區分
        str:=str+'====>'+E.Message;
        ss.Add(str);
      end;
    end;
    DBGrid1.DataSource.DataSet.Next;
  end;
  //..ss裡儲存的都是儲存失敗的資料,做個處理吧,看是存成文字檔還是show給user看
  ss.free;
end;
在except-end之間,不要去raise錯誤,而把錯誤訊息存入ss裡,就可以繼續下一筆的動作了
dino
一般會員


發表:20
回覆:73
積分:23
註冊:2002-07-29

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-08 21:15:32 IP:61.219.xxx.xxx 未訂閱
change.jian 兄 你好 感謝你的回答,好像TStringList是個蠻好用的物件 小弟剛好有個問題在Object Pascal討論區那邊提問 有好心的朋友回答說可以用TStringList來解決 只是不知道要怎麼用TStringList來做檔案搜尋的動作 問題在下面,可否給晚輩提點一下,謝謝 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=59391
dino
一般會員


發表:20
回覆:73
積分:23
註冊:2002-07-29

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-09 12:55:31 IP:61.219.xxx.xxx 未訂閱
likush 兄 感謝你的回答 我試不出來,我要比對的是兩個不同的資料庫中一模一樣的table 我用SQL Query Analyzer去下指令,問題是SQL Query Analyzer 一次只能連結一個資料庫,要怎麼樣才能跨兩個資料庫去查詢呢? select field1,field2,field3 from X  where field1 in (select field1 from X) A資料庫跟B資料庫都有 X 這個table
dino
一般會員


發表:20
回覆:73
積分:23
註冊:2002-07-29

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-10 17:32:51 IP:61.219.xxx.xxx 未訂閱
後來發現可以用資料庫名稱.dbo.table名稱 就可以查詢到別的資料庫 裡面的table 但是唯一值是是由3個欄位所組成 我試過 select field1,field2,field3 from sourceDB.dbo.table where field1 in (select field1 from destDB.dbo.table) where後面只能接一個欄位,那要怎麼selete出由3個欄位構成的唯一值呢? 發表人 - dino 於 2004/11/10 17:36:19
系統時間:2024-06-29 9:15:59
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!