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

要怎麼在ADOquery斷線之後,不會跳出錯誤訊息;而且連線之後ADOquery又能接自動接上

尚未結案
chawei
一般會員


發表:2
回覆:5
積分:1
註冊:2009-01-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-04-14 16:05:01 IP:60.249.xxx.xxx 訂閱
小弟最近寫了一支程式,寫好之後放在客戶端,這支程式會每份鐘去主機抓一次資料,
某次主機關機維護之後,它就跳一個錯誤訊息,顯示ADOQuery斷線的錯誤訊息,程式就不會動了

想請問各位,當主機關機或斷線之後,雖然資料抓不到,但有沒有辦法讓我的程式不會當機?
有沒辦法在主機重新開機之後又能繼續抓資料?
不然只要主機關機或是線路不稱斷線之後,我又要去客戶那裡幫他重開機

我是使用ADOQuery接MS-SQL

謝謝
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-04-14 16:23:02 IP:60.248.xxx.xxx 訂閱
看您的問題,您自己似乎就有解,既然知道是在 ADOQuery 在查時會當,
您有用 try.except 的方式讓程式繼續正常運作嗎?

或是您只有一個 Main Thread 來重新連 connection ,所以在重新 connection 時,系統會卡住等待連線,
如果是這樣,那可以用 MultiThread 來解決,並且在畫面提示 user ,目前主機維護中之類的訊息
------
價值的展現,來自於你用哪一個角度來看待它!!
chawei
一般會員


發表:2
回覆:5
積分:1
註冊:2009-01-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-04-14 16:53:26 IP:60.249.xxx.xxx 訂閱
我有參考你的建議用try except去做,當我手動把它斷線之後,過了約一分鐘它就會跳出這個錯誤訊息,我不瞭解為什麼這個錯誤抓不到 
Project Project1.exe raised exception class EOleException with message '[DBNETLIB][ConnectionOpen (Connect()).]SQL Server不存在或拒絶存取

附我的程式碼,幫忙看有沒有問題,
我是放在Timer裡面,每五秒抓一次資料
然後用手動方式把網路斷掉,斷掉的當時並沒有出錯,可是約一分鐘之後就跳上面的錯誤訊息
謝謝

[code delphi]
procedure TForm1.Timer1Timer(Sender: TObject);
var
sTemp : string;
begin
Timer1.Enabled :=False;
try
ADOQuery := TADOQuery.Create(nil);
DataSource := TDataSource.Create(nil);

sTemp := 'Network Library=dbmssocn;'
'Provider=SQLOLEDB.1;'
'Persist Security Info=True;'
'User ID=xxxxxx;'
'Password=xxxxxx;'
'Initial Catalog=xxxxxx;'
'Data Source=xx.xx.xx.xx';

ADOQuery.ConnectionString := sTemp;
DataSource.dataset := ADOQuery;

ADOQuery.SQL.Text := 'select * from xxxxx';
ADOQuery.Open;
if not DataSource.DataSet.Eof then
Edit1.text := DataSource.DataSet.FieldByName('xxxx').asString;
ADOQuery.Close;
ADOQuery.Free;

Except
ADOQuery.Close;
ADOQuery.Free;
end;
Timer1.Enabled := TRUe;

end;
[/code]

編輯記錄
chawei 重新編輯於 2010-04-14 16:54:50, 註解 無‧
ko
資深會員


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-04-14 17:05:38 IP:61.66.xxx.xxx 訂閱
因為您MS SQL SERVER的 TIME OUT設定60秒
------
======================
昏睡~
不昏睡~
不由昏睡~
chawei
一般會員


發表:2
回覆:5
積分:1
註冊:2009-01-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-04-15 09:22:17 IP:60.249.xxx.xxx 訂閱
我在上述的程式碼中加上了 
TADODataset(ADOQuery).CommandTimeout := 600;
可是沒有如預期的錯誤時間出現的比較晚
chawei
一般會員


發表:2
回覆:5
積分:1
註冊:2009-01-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-04-15 09:29:32 IP:60.249.xxx.xxx 訂閱
我用單步執行去測試,發現手動斷線後它會停在這一行
ADOQuery.SQL.Text := 'select * from xxxxx';
過很久才會出現錯誤訊息

很奇怪的是前面的 ADOQuery.ConnectionString := sTemp; 就能給它值
為什麼ADOQuery.SQL.Text := 'select * from xxxxx'; 就會出錯,同樣是給它值啊?

還有沒有什麼辦法可以讓這個錯誤訊息不要出現?

謝謝
P.D.
版主


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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-04-15 10:17:07 IP:118.169.xxx.xxx 未訂閱
兩點疑問
1. 在 TRY 中建立 adoquery , 連結失敗或其他原因失敗, 代表這個連結是不存在, 那會觸發 except 機制, 可是except 中又有 ADOQUERY1.close, 即然 adoquery 沒有連結, 如何有 close, 拿掉這個試試看
2. 每5秒就要作業一次, 系統5秒內要建立 adoquery, 要解譯, 時間是否足夠, 又再者, 一分鐘要進行12次, 這對sql server 其實負荷很大, 我的做法, 類似這樣的狀況, adoquery 會在 create 時就先建立起來, 或者直接使用 ADO元件放置在版上, 減少 系統重覆建立的損耗
以上純屬個人看法, 若有論述不對, 請見諒!
chawei
一般會員


發表:2
回覆:5
積分:1
註冊:2009-01-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2010-04-15 13:40:39 IP:60.249.xxx.xxx 訂閱

===================引 用 P.D. 文 章===================
兩點疑問
1. 在 TRY 中建立 adoquery , 連結失敗或其他原因失敗, 代表這個連結是不存在, 那會觸發 except 機制, 可是except 中又有 ADOQUERY1.close, 即然 adoquery 沒有連結, 如何有 close, 拿掉這個試試看
2. 每5秒就要作業一次, 系統5秒內要建立 adoquery, 要解譯, 時間是否足夠, 又再者, 一分鐘要進行12次, 這對sql server 其實負荷很大, 我的做法, 類似這樣的狀況, adoquery 會在 create 時就先建立起來, 或者直接使用 ADO元件放置在版上, 減少 系統重覆建立的損耗
以上純屬個人看法, 若有論述不對, 請見諒!

1.ADOQuery.close已經拿掉, 對程式沒有影響, 不過錯誤訊息還是會出現

2.5秒跑一次其實時間是夠的,而且我在OnTimer的事件中,第一行就是把這個Timer disable掉,所以它會等裡面的內容都跑完成才會再觸發下一次的onTimer

3.ADOQuery在Create時就建立的做法,我會試試看

謝謝
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-04-15 16:50:56 IP:59.125.xxx.xxx 訂閱
===================引 用 chawei 文 章===================
ADOQuery.ConnectionString := sTemp;

只是給 ConnectionString 值,
不連線

===================引 用 chawei 文 章===================
ADOQuery.SQL.Text := 'select * from xxxxx';

要 Parse SQL,需要連線。所以停在這裡是合理的
過很久才會出現錯誤訊息是因為 Connection Timeout 太長的關係

===================引 用 chawei 文 章===================
TADODataset(ADOQuery).CommandTimeout := 600;

這是 Command Timeout,不是 Connection Timeout
建議你用一個 TADOConnection 來負責連線
TADOConnection 有 ConnectionTimeout 屬性可以設定

------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
glings
一般會員


發表:18
回覆:9
積分:5
註冊:2006-07-17

發送簡訊給我
#10 引用回覆 回覆 發表時間:2010-08-04 16:03:25 IP:220.179.xxx.xxx 訂閱
不知你的问题解决了没有?我也遇到相同的问题:当程序启动时网络联通,就都正常,当网络断开,再联上后(数据库在网络的一台机器上)执行adoquery.open时就出错,此时

已执行了adoconnection.connect ed:=true ,请大家帮助分析原因。
glings
一般會員


發表:18
回覆:9
積分:5
註冊:2006-07-17

發送簡訊給我
#11 引用回覆 回覆 發表時間:2010-08-06 10:06:58 IP:220.179.xxx.xxx 訂閱
我这样做:首先此程序是个循环(如用Timer),在主体中要不断测与服务器的连通情况,当断开联接时会出现异常,可屏蔽它(能给出出错信息最好),主体就在‘安静’中循环。
不能用adoconnection的connected的值,来判断,它只是某个时间事件触发的值,不能用它来确定‘现在’的值,只有当query的active能为true时,它才可信,用一条测试的SQL语句来open 一下:
ADOConnection1.Close;//一定要先close一下,在线路通时,才能再次联上;
adoconnection1.Connected:=true;
adoquery1.SQL.Clear;
adoquery1.SQL.Add('select top 1 XX from XX ');
try
adoquery1.Open;
if adoquery1.Active=true then result:=true;
except
memo1.Lines.Add('数据库没有联接,请等待!');
end ;
TIMER的值的问题,在一次触发中,如果此次执行可能时间很长,如3分钟(很夸大),也不用担心,毕竟要到执行完才开始下一次的触发执行。
編輯記錄
glings 重新編輯於 2010-08-06 10:12:52, 註解 無‧
glings 重新編輯於 2010-08-06 10:15:36, 註解 無‧
smallfox
高階會員


發表:2
回覆:113
積分:128
註冊:2003-02-19

發送簡訊給我
#12 引用回覆 回覆 發表時間:2010-08-09 17:06:54 IP:220.130.xxx.xxx 訂閱

加入下列指令試看看:

try
.....
if (ADOQuery1.Connection.Connected) then ADOQuery1.Connection.Connected:=False;
ADOQuery1.Open;
....
except
if (ADOQuery1.Connection.Connected) then ADOQuery1.Connection.Connected:=False;
ADOQuery1.Close;
....
end;

tempone1
一般會員


發表:0
回覆:4
積分:0
註冊:2010-11-23

發送簡訊給我
#13 引用回覆 回覆 發表時間:2010-11-24 11:31:40 IP:124.160.xxx.xxx 訂閱
TRY 
EXCEPT
E:OLEEXCPTION ON
BEGIN
//所設置的顯示出來異常
END;
END;
TIMER1中這樣,效果是個問題。
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#14 引用回覆 回覆 發表時間:2010-11-30 11:39:19 IP:124.65.xxx.xxx 訂閱
小動作,大家都沒有在乎到
adoconnection.connected := true後
大多人的動作就是ADOQuery.Close or ADODatSet.Close;
這樣其實在網路斷線時,ADO仍會認定是連線的,
為何呢因為adoconnection.KeepConnection := true;
所以ADO只要連線了都會默認是網路是“通“的,
最後的導致結果就是這樣...
所以,對SQL做任何動作前最好,
adoconnection.connected := false
ADOQuery.Close;
....
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add(SQL);
ADOQuery.Open;


===================引 用 chawei 文 章===================
小弟最近寫了一支程式,寫好之後放在客戶端,這支程式會每份鐘去主機抓一次資料,
某次主機關機維護之後,它就跳一個錯誤訊息,顯示ADOQuery斷線的錯誤訊息,程式就不會動了

想請問各位,當主機關機或斷線之後,雖然資料抓不到,但有沒有辦法讓我的程式不會當機?
有沒辦法在主機重新開機之後又能繼續抓資料?
不然只要主機關機或是線路不稱斷線之後,我又要去客戶那裡幫他重開機

我是使用ADOQuery接MS-SQL

謝謝
------
程式沒有這麼難
只是還沒打通其中要絕
momomo
一般會員


發表:3
回覆:2
積分:1
註冊:2006-12-20

發送簡訊給我
#15 引用回覆 回覆 發表時間:2011-02-11 22:06:08 IP:218.4.xxx.xxx 訂閱

[code delphi]
procedure TDM.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
if (E is EOleException) and (pos('连接失败',E.Message)>0) then
if MsgYesNoBox(Format('数据库连接被意外中止,要重新连接吗? ' #10#13 '错误原因:%s ',[E.Message])) then
begin
MainConnection.Close;
MainConnection.Connectionstring := ReturnStr;
MainConnection.Connected := True;
end;
end;
[/code]
Louis_H
一般會員


發表:7
回覆:19
積分:10
註冊:2005-10-07

發送簡訊給我
#16 引用回覆 回覆 發表時間:2011-06-17 17:21:30 IP:59.120.xxx.xxx 訂閱
剛好最近也有遇到相同問題...
爬文加上自己不斷測試結果如下:( BCB 6 MySQL )
首先..會觸發 知道無法連接資料庫 最直接的地方在 ADOQuery->Active
(主程序 某個自動執行 Timer 內容)
try
{
this->ADOQuery1->Active = False;
this->ADOQuery1->Active = True;
}
catch(...)
{
if( DisconnectFrm->Timer1->Enabled == false )
{
DisconnectFrm->ShowModal() ;
return;
}
}
在確認 ADOQuery1 的 SQL 內容正確的前提下,會進 catch 視為斷線
主程式便會 出現 目前已斷線提示 視窗
(目前已斷線提示 程序中某個自動執行 Timer 內容)

try
{
ProcessMainFrm->cmsConnection1->Close() ;
ProcessMainFrm->cmsConnection1->ConnectionTimeout = 1;
ProcessMainFrm->cmsConnection1->Open() ;
ADOQuery->Active = False;
ADOQuery->Active = True; // 隨便一段 Select 資料庫即可..測試用
btnCloseClick(0);
}
catch(...)
{
return;
}

(目前已斷線提示 程序中FormShow()內容)

Timer1->Enabled = true;

(目前已斷線提示 程序中btnCloseClick() 內容)

Timer1->Enabled = false;
ProcessMainFrm->cmsConnection1->Close() ;
ProcessMainFrm->cmsConnection1->ConnectionTimeout = 15;
ProcessMainFrm->cmsConnection1->Open() ;
Close();

說明:其實ADOConnection 在 BCB6 裡面它的 Events 都不實際
通常它的 ConnectionTimeout 預設值都是 15 秒..( 很久 )
上述在確定它與資料庫斷線之後,為了能一直去 ReConnection
必需將 ConnectionTimeout 設為 1 秒..( 配合 Timer ..一般 Timer 都會設小於 1000 = 1 秒 )
如此在確定又連線上了之後,再恢復原來的設定值,關掉 目前已斷線提示 視窗即可。







cancer
高階會員


發表:58
回覆:319
積分:190
註冊:2004-07-31

發送簡訊給我
#17 引用回覆 回覆 發表時間:2011-06-21 17:16:26 IP:220.128.xxx.xxx 未訂閱
Hello, 太多回應,先不看。
最簡單的方法是,每次讀取資料之前,都把 Connection 元件重新連線,讀完資料,都處理過之後,Query.Close 之後,再加上 Connection.Close。
pprayer
高階會員


發表:35
回覆:185
積分:174
註冊:2002-03-13

發送簡訊給我
#18 引用回覆 回覆 發表時間:2011-07-16 14:12:36 IP:114.32.xxx.xxx 訂閱
是不是讓ADOQuery先連結一個ADOConntection比較好呢?
ADOConnection 連線失敗是可以被Try..Except攔截的

或者你可以另外弄一支副程式偵查資料庫的Service是否running
確定Service有起來再做其他的事情

===================引 用 chawei 文 章===================
小弟最近寫了一支程式,寫好之後放在客戶端,這支程式會每份鐘去主機抓一次資料,
某次主機關機維護之後,它就跳一個錯誤訊息,顯示ADOQuery斷線的錯誤訊息,程式就不會動了

想請問各位,當主機關機或斷線之後,雖然資料抓不到,但有沒有辦法讓我的程式不會當機?
有沒辦法在主機重新開機之後又能繼續抓資料?
不然只要主機關機或是線路不稱斷線之後,我又要去客戶那裡幫他重開機

我是使用ADOQuery接MS-SQL

謝謝
系統時間:2024-11-05 13:00:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!