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

try...except 中若處理例外錯誤,會中斷外層迴圈??

尚未結案
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-02-02 15:11:51 IP:211.21.xxx.xxx 未訂閱
小弟我目前作一個程式 目的是用迴圈將某一目錄下的 *.sql (SQL Script 檔) 一個一個讀到 TQury 中,然後執行 execsql 方法 並使用 try..except 以便抓到 sql 處理失敗的檔案顯示在 Memo1 中    但每次有錯誤時,整個迴圈就停了 但若不處理例外(也就是 catch 中不放任何程式碼) 迴圈就會繼續(無聲的例外,但就不知執行中有沒有錯誤) 我不知各位長官是否有方法讓 except 處理後,迴圈能繼續 因為就算執行到其中某一 SQL Script 就算有錯 , 也不代表下一個 SQL Script 也有錯    
 
for i:= 0 to FileListBox1.Count-1 do
  begin
    fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i];
    curr_fn:=FileListBox1.Items.Strings[i];        Memo1.Lines.Add('處理 ' curr_fn);        Query1.close;
    Query1.sql.clear;
    Query1.sql.LoadFromFile(fn);
    try
      Query1.execsql;
    except
      //由於捕捉訊息會中斷迴圈,故不處理任何被捕捉到的訊息
      //  Memo1.Lines.Add(FileListBox1.Items.Strings[i] ' 處理失敗');
    end;        ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count));
    Application.ProcessMessages();      end;    
terrychen
尊榮會員


發表:90
回覆:794
積分:501
註冊:2003-05-01

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-02-02 16:00:14 IP:61.221.xxx.xxx 未訂閱
您好: 不知道有無誤解您的意思 tools=>debugger options=>language exceptions=>stop on delphi exceptions 將和取方塊取消 就不會因錯誤中斷回圈 小弟認為版主應有注意到此點 只是小弟做了如下的測試,可順利將錯誤ADD至MEMO中
 
procedure TForm1.Button1Click(Sender: TObject);
Var
  i:integer;
begin
  ADOQuery1.Open;
  for i := 0 to ADOQuery1.RecordCount- 1 do
  begin
  try
    ADOQuery2.ExecSQL;//故意出錯
  except
    Memo1.Lines.Add('err');
  end;
  end;
end;
~~應無所住而生其心~~ 發表人 - Terrychen 於 2004/02/02 16:10:46
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-02-02 16:38:55 IP:203.222.xxx.xxx 未訂閱
錯誤保護 try 的例外產生時,會一直影響程式往外延伸擴大直到再度遇到 try 所以我想你可以用兩層 try 試試看
for i:= 0 to FileListBox1.Count-1 do
 begin      fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i];
  curr_fn:=FileListBox1.Items.Strings[i];
  Memo1.Lines.Add('處理 ' curr_fn);
  Query1.close;
  Query1.sql.clear;
  Query1.sql.LoadFromFile(fn);
  try       try        Query1.execsql;       except
    這樣應該可以不用關閉 Delphi 內定的例外機制,並加以處理例外狀況 
    //由於捕捉訊息會中斷迴圈,故不處理任何被捕捉到的訊息
    //  Memo1.Lines.Add(FileListBox1.Items.Strings[i] ' 處理失敗');
   end;      finally      end;      ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count));
  Application.ProcessMessages();     end;
timhuang
尊榮會員


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-02-02 17:59:06 IP:203.95.xxx.xxx 未訂閱
Hi, bruce0211 兄, 弟實測過, 在迴圈中有 error, 利用 try.. except.. end; 的方式處理, 並不會跳出迴圈. 推測是不是因為 sql command 內有什麼特別的語法造成 delphi 無法 handle 的 error 呢? 可否請教一下該錯誤訊息是什麼呢?
ko
資深會員


發表:28
回覆:785
積分:444
註冊:2002-08-14

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-02-02 18:19:43 IP:61.221.xxx.xxx 未訂閱
bruce0211 你好: 或許要試一下成功Commit失敗Rollback
------
======================
昏睡~
不昏睡~
不由昏睡~
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-02-03 11:25:11 IP:211.21.xxx.xxx 未訂閱
感謝各位長官 我再嚴僅的測試一遍 發覺研究方法有誤 try..except 真的不會中斷迴圈    其實是我放了一個ApplicationEvents 元件在 Form 上 在 try except 中我放了一個 raise 抓到錯誤時將 錯誤 raise 出去給ApplicationEvents 元件 (因為我不知道如何將 Exception 變成文字紀錄起來 我只會使用ApplicationEvents 元件中丟出來的 E.Message 這個東西)    但利用 ApplicationEvents 元件抓取錯誤時 真的會中斷迴圈的執行
 
procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
  E: Exception);
begin
  if curr_fn<>'' then Memo1.Lines.Add(curr_fn ' 處理失敗');
  Memo1.Lines.Add(E.Message);
  Memo1.Lines.Add('');
end;
我後來找到直接在 try..except 中紀錄錯誤的方法(不透過ApplicationEvents 元件就不會中斷迴圈)如下
try
  Query1.execsql;
except
  on E: EDBEngineError do  //處理資料庫引擎錯誤
     begin
     end;
  on E: EExternalError do  //處理視窗類錯誤
     begin
     end;
  on E: Exception do       //處理所有 VCL 錯誤
     begin
       Memo1.Lines.Add(E.Message);
     end;
end;
 
BCB 版如下
try 
  {
  Query1->ExecSQL();   
  }
catch(EDBEngineError &E) //處理資料庫引擎錯誤
  {
  }
catch(EExternalError &E) //處理視窗類錯誤
  {
  }
catch(Exception &E) //處理所有 VCL 錯誤
  {
    Memo1->Lines->Add(E.Message);
  }
 
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-02-03 12:02:12 IP:61.222.xxx.xxx 未訂閱
班門弄斧一下,紀錄錯誤訊息    
     try
   ADOQuery.ExecSQL;
 except
   on E:Exception do
   begin
     showmessage('執行階段錯誤: '   E.ClassName);
     SaveErr(E);
   end;
 end;    procedure SaveErr(E:Exception);
var s1  : string;
    st : TStringList;
begin
 s1 := ExtractFilePath(Application.EXEName)   'err.txt';
 st := TStringList.Create;
 try
  if FileExists(s1) then 
  begin
     st.LoadFromFile(sFileName);
  end;
  st.Add(FormatDateTime('yyyy/mm/dd hh:nn am/pm', Now);
  st.Add(ClassName '-' E.Message);
  st.SaveToFile(sFileName);
 finally
  st.Free;
 end;
end;
shaofu
高階會員


發表:5
回覆:136
積分:103
註冊:2003-01-07

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-02-03 13:30:08 IP:210.243.xxx.xxx 未訂閱
引言: 其實是我放了一個ApplicationEvents 元件在 Form 上 在 try except 中我放了一個 raise 抓到錯誤時將 錯誤 raise 出去給ApplicationEvents 元件 (因為我不知道如何將 Exception 變成文字紀錄起來 我只會使用ApplicationEvents 元件中丟出來的 E.Message 這個東西) 但利用 ApplicationEvents 元件抓取錯誤時 真的會中斷迴圈的執行
不是 ApplicationEvents 的原因, 是因為你 raise 的關係
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-02-03 13:46:08 IP:211.21.xxx.xxx 未訂閱
引言: 不是 ApplicationEvents 的原因, 是因為你 raise 的關係 < face="Verdana, Arial, Helvetica"> 可是我試過 若再回圈中不用 try ... except 直接執行 Query1.execsql; 如下
for i:= 0 to FileListBox1.Count-1 do
 begin      fn := FileListBox1.Directory '\' FileListBox1.Items.Strings[i];
  curr_fn:=FileListBox1.Items.Strings[i];
  Memo1.Lines.Add('處理 ' curr_fn);
  Query1.close;
  Query1.sql.clear;
  Query1.sql.LoadFromFile(fn);
 
  Query1.execsql;      ProgressBar1.Position:=Trunc(((i 1)*100)/(FileListBox1.Count));
  Application.ProcessMessages();     end;
 
當有錯誤發生, ApplicationEvents 元件仍抓得到例外錯誤,但迴圈一樣被中斷... 先前的作法其實有點"脫褲子放X",藉由 try...except 欄例外錯誤,再轉手將欄到的例外錯誤 raise 給 ApplicationEvents 元件, 反正 ApplicationEvents 元件只要有處理例外,迴圈就終止了 若 try..except 未 raise , 發生錯誤時, try..except 就"自行吸收",ApplicationEvents 元件就抓不到例外, 我只知道 raise 是把抓到的錯誤,"再"丟出去 ...
shaofu
高階會員


發表:5
回覆:136
積分:103
註冊:2003-01-07

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-02-03 14:24:14 IP:210.243.xxx.xxx 未訂閱
就如大家前面說的..  是因為 Exception 會往外擴散, 直到有人處理他為止  沒人處理, 迴圈被中斷是一定會的... > > 中斷迴圈 -> > > 被你攔截了, 但又 > > 中斷迴圈 -> > > 被你攔截了, > 迴圈繼續 > 發表人 -
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-02-03 14:43:01 IP:211.21.xxx.xxx 未訂閱
引言: 班門弄斧一下,紀錄錯誤訊息
謝謝各位長官的指教 特別是 hahalin 長官提供現成好用的範例
系統時間:2024-05-07 22:02:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!