procedure TData1.DataModuleCreate(Sender: TObject);
var filename:string;
begin
filename:=ExtractFilePath(paramstr(0))+'myini.ini';
myinifile:=TInifile.Create(filename);
version:=myinifile.ReadString('ServerInfo','version','');
ADOConnection1.ConnectionString:= 'Provider=SQLOLEDB.1;Password='+myinifile.readstring('ServerInfo','SQLPwd','')+';Persist Security Info=True;User ID='+myinifile.readstring('ServerInfo','SQLUserID','')+';Initial Catalog='+myinifile.readstring('ServerInfo','SQLDBName','')+';Data Source='+myinifile.readstring ('ServerInfo','ServerIP','');
end;
窗体中U_ygbm 的刷新代码
adoquery1 (连接上面的ADOConnection1)
with adoquery1 do
begin
close;
sql.Clear;
sql.Add('select * from tba_ygbm');
open;
end;
在进销存中如果网线断网后再刷新会提示连接失败,如果网络正常后也要退出整个程序后才能再进入操作,刷新也没用
有些程序可以实现重新连接,如何实现呢
29 个解决方案
#1
连接代码再执行一遍
#2
搞个TIMER控件,隔段时间检查一下是否连接正常,如果断开了,再执行一次连接代码 !
#3
把里面的 KeepConnection 属性给 False 了
以后用一次连一次
以后用一次连一次
#4
我试试,有点麻烦
#5
with adoquery1 do
begin
Connection := data1.ADOConnection1;
Close;
SQL.Clear;
sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
try
try
data1.ADOConnection1.Connected := false;
data1.ADOConnection1.Connected := true;
except
end;
adoquery1.Open;
except
end;
end;
还是不行
begin
Connection := data1.ADOConnection1;
Close;
SQL.Clear;
sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
try
try
data1.ADOConnection1.Connected := false;
data1.ADOConnection1.Connected := true;
except
end;
adoquery1.Open;
except
end;
end;
还是不行
#6
var
adoq : TADOQuery;
begin
adoq := TADOQuery.Create(nil);
adoq.Connection := dm.ADOConn;
adoq.Close;
adoq.SQL.Clear;
adoq.SQL.Add('select * from cat where 1=0');
try
try
if dm.ADOConn.Connected then
dm.ADOConn.Connected := false;
dm.ADOConn.Connected := true;
except
end;
adoq.Open;
except
end;
end;
或者
try
while dm.ADOConn.Connected=true do
begin
dm.ADOConn.Connected := false;
application.ProcessMessages;
end;
while dm.ADOConn.Connected=false do
begin
dm.ADOConn.Connected := true;
application.ProcessMessages;
end;
except
end;
都可以,不过太影响速度了,有没有简单点办法
adoq : TADOQuery;
begin
adoq := TADOQuery.Create(nil);
adoq.Connection := dm.ADOConn;
adoq.Close;
adoq.SQL.Clear;
adoq.SQL.Add('select * from cat where 1=0');
try
try
if dm.ADOConn.Connected then
dm.ADOConn.Connected := false;
dm.ADOConn.Connected := true;
except
end;
adoq.Open;
except
end;
end;
或者
try
while dm.ADOConn.Connected=true do
begin
dm.ADOConn.Connected := false;
application.ProcessMessages;
end;
while dm.ADOConn.Connected=false do
begin
dm.ADOConn.Connected := true;
application.ProcessMessages;
end;
except
end;
都可以,不过太影响速度了,有没有简单点办法
#7
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false;
ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free;
if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end;
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false;
ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free;
if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end;
#8
在执行操作前,判断一下adoconnection是否联接正常。
#9
不需要吧
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的
#10
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。
解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。
楼主可以试试。
解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。
楼主可以试试。
#11
现是是可以了,首选会提示连接失败,我刷新会提示连接超时,再确定就连上去了,但是太耗时间了
#12
你像我一样把检测代码放在时钟里执行嘛,这样的话,当网络重新连通后,ADOConnection就会在后台悄悄重连了
#13
@xuxugr, @ahhjgh
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。
#14
用time事件,你是每多少时间检测一次,而且这样话是不是非常影响速度呢,耗用服务器资源呢
#15
几秒检测一次,因为重连之前,我是先PING服务器的,如果不通的话,就不会去打开ADOCONNECTION,所以不会耗费服务器资源的,也基本不耗费客户端资源,整个过程不会产生检测延时,造成假死的现象
#16
路过,学习!
#17
这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充.
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
trylinkado:tadoquery;
begin
result:=False;
trylinkado:=tadoquery.Create(nil);
testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';
trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
trylinkado.CommandTimeout:=2;
try
trylinkado.SQL.Add('select 1 "nettest"');
trylinkado.Open;
trylinkado.Close;
Result:=True;
except
Result:=false;
end;
trylinkado.Free;
end;
2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连
3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
dm.ADOConnection1.Connected:=True;
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
;
end;
end;
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
trylinkado:tadoquery;
begin
result:=False;
trylinkado:=tadoquery.Create(nil);
testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';
trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
trylinkado.CommandTimeout:=2;
try
trylinkado.SQL.Add('select 1 "nettest"');
trylinkado.Open;
trylinkado.Close;
Result:=True;
except
Result:=false;
end;
trylinkado.Free;
end;
2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连
3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
dm.ADOConnection1.Connected:=True;
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
;
end;
end;
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的
#18
在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用
#19
这个方法比较耗费资源,并且会造成假死现象,因为:
1、当网络正常时,这种方法还是会频繁查询数据库,造成资源浪费;
2、当网络断开时,该方法会造成假死现象,首先调用canlink时,因为网络不通,会有延时等待,并且必定返回FALSE,这时又会去重连数据库,又会造成更大的延时等待。检测、重连循环进行,不断的假死,直到网络正常为止
#20
to ahhigh
你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.
另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?
你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.
另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?
#21
头痛,没人知道吗
#22
data module没有time事件呀,难道在进入系统的主窗体再做一个
#23
当数据库连接成功后,如果KeepConnection=True,那碰到连接断开时Connected属性仍未True。这个时候可以在OnExecuteComplete里面可以调用Close把Connection关闭。我的意思是根据网络情况适当调整ConnectionTimeout和CommandTimeout的值,来减少超时时间。这对于采用同步连接的ADO来说,永远无法避免,使用Timer也是如此。
#24
ahhjigh
你能把form1,form2里的源代码全部发给我吗,麻烦你了,我是新手
gr.xu@yahoo.com.cn
#25
我就不相信delphi没有好的解决方法吗
#26
加一个timer控件.
#27
呵呵!好像没那么简单,因为在保存时比较理想的做法时保存时如果断线就会延迟10秒再执行,直到保存为止,除非退出
#28
使用IPWORKS 控件实现PINGSERVER函数
function TForm2.PingServer(ServerIp:string):boolean;
begin
Result := True;
ipwPing1.Timeout := 1;
Try
ipwPing1.PingHost(ServerIp);
Except
Result := False;
end;
end;
function TForm2.PingServer(ServerIp:string):boolean;
begin
Result := True;
ipwPing1.Timeout := 1;
Try
ipwPing1.PingHost(ServerIp);
Except
Result := False;
end;
end;
#29
我提供的解决方案里面的timer2,timer3都是我的系统的业务逻辑,你不必关心
#1
连接代码再执行一遍
#2
搞个TIMER控件,隔段时间检查一下是否连接正常,如果断开了,再执行一次连接代码 !
#3
把里面的 KeepConnection 属性给 False 了
以后用一次连一次
以后用一次连一次
#4
我试试,有点麻烦
#5
with adoquery1 do
begin
Connection := data1.ADOConnection1;
Close;
SQL.Clear;
sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
try
try
data1.ADOConnection1.Connected := false;
data1.ADOConnection1.Connected := true;
except
end;
adoquery1.Open;
except
end;
end;
还是不行
begin
Connection := data1.ADOConnection1;
Close;
SQL.Clear;
sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
try
try
data1.ADOConnection1.Connected := false;
data1.ADOConnection1.Connected := true;
except
end;
adoquery1.Open;
except
end;
end;
还是不行
#6
var
adoq : TADOQuery;
begin
adoq := TADOQuery.Create(nil);
adoq.Connection := dm.ADOConn;
adoq.Close;
adoq.SQL.Clear;
adoq.SQL.Add('select * from cat where 1=0');
try
try
if dm.ADOConn.Connected then
dm.ADOConn.Connected := false;
dm.ADOConn.Connected := true;
except
end;
adoq.Open;
except
end;
end;
或者
try
while dm.ADOConn.Connected=true do
begin
dm.ADOConn.Connected := false;
application.ProcessMessages;
end;
while dm.ADOConn.Connected=false do
begin
dm.ADOConn.Connected := true;
application.ProcessMessages;
end;
except
end;
都可以,不过太影响速度了,有没有简单点办法
adoq : TADOQuery;
begin
adoq := TADOQuery.Create(nil);
adoq.Connection := dm.ADOConn;
adoq.Close;
adoq.SQL.Clear;
adoq.SQL.Add('select * from cat where 1=0');
try
try
if dm.ADOConn.Connected then
dm.ADOConn.Connected := false;
dm.ADOConn.Connected := true;
except
end;
adoq.Open;
except
end;
end;
或者
try
while dm.ADOConn.Connected=true do
begin
dm.ADOConn.Connected := false;
application.ProcessMessages;
end;
while dm.ADOConn.Connected=false do
begin
dm.ADOConn.Connected := true;
application.ProcessMessages;
end;
except
end;
都可以,不过太影响速度了,有没有简单点办法
#7
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false;
ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free;
if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end;
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false;
ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free;
if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end;
#8
在执行操作前,判断一下adoconnection是否联接正常。
#9
不需要吧
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的
#10
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。
解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。
楼主可以试试。
解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。
楼主可以试试。
#11
现是是可以了,首选会提示连接失败,我刷新会提示连接超时,再确定就连上去了,但是太耗时间了
#12
你像我一样把检测代码放在时钟里执行嘛,这样的话,当网络重新连通后,ADOConnection就会在后台悄悄重连了
#13
@xuxugr, @ahhjgh
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。
#14
用time事件,你是每多少时间检测一次,而且这样话是不是非常影响速度呢,耗用服务器资源呢
#15
几秒检测一次,因为重连之前,我是先PING服务器的,如果不通的话,就不会去打开ADOCONNECTION,所以不会耗费服务器资源的,也基本不耗费客户端资源,整个过程不会产生检测延时,造成假死的现象
#16
路过,学习!
#17
这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充.
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
trylinkado:tadoquery;
begin
result:=False;
trylinkado:=tadoquery.Create(nil);
testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';
trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
trylinkado.CommandTimeout:=2;
try
trylinkado.SQL.Add('select 1 "nettest"');
trylinkado.Open;
trylinkado.Close;
Result:=True;
except
Result:=false;
end;
trylinkado.Free;
end;
2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连
3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
dm.ADOConnection1.Connected:=True;
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
;
end;
end;
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
trylinkado:tadoquery;
begin
result:=False;
trylinkado:=tadoquery.Create(nil);
testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';
trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
trylinkado.CommandTimeout:=2;
try
trylinkado.SQL.Add('select 1 "nettest"');
trylinkado.Open;
trylinkado.Close;
Result:=True;
except
Result:=false;
end;
trylinkado.Free;
end;
2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连
3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
dm.ADOConnection1.Connected:=True;
try
DM.ADOConnection1.Execute('select 1 "nettest"');
except
;
end;
end;
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的
#18
在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用
#19
这个方法比较耗费资源,并且会造成假死现象,因为:
1、当网络正常时,这种方法还是会频繁查询数据库,造成资源浪费;
2、当网络断开时,该方法会造成假死现象,首先调用canlink时,因为网络不通,会有延时等待,并且必定返回FALSE,这时又会去重连数据库,又会造成更大的延时等待。检测、重连循环进行,不断的假死,直到网络正常为止
#20
to ahhigh
你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.
另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?
你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.
另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?
#21
头痛,没人知道吗
#22
data module没有time事件呀,难道在进入系统的主窗体再做一个
#23
当数据库连接成功后,如果KeepConnection=True,那碰到连接断开时Connected属性仍未True。这个时候可以在OnExecuteComplete里面可以调用Close把Connection关闭。我的意思是根据网络情况适当调整ConnectionTimeout和CommandTimeout的值,来减少超时时间。这对于采用同步连接的ADO来说,永远无法避免,使用Timer也是如此。
#24
ahhjigh
你能把form1,form2里的源代码全部发给我吗,麻烦你了,我是新手
gr.xu@yahoo.com.cn
#25
我就不相信delphi没有好的解决方法吗
#26
加一个timer控件.
#27
呵呵!好像没那么简单,因为在保存时比较理想的做法时保存时如果断线就会延迟10秒再执行,直到保存为止,除非退出
#28
使用IPWORKS 控件实现PINGSERVER函数
function TForm2.PingServer(ServerIp:string):boolean;
begin
Result := True;
ipwPing1.Timeout := 1;
Try
ipwPing1.PingHost(ServerIp);
Except
Result := False;
end;
end;
function TForm2.PingServer(ServerIp:string):boolean;
begin
Result := True;
ipwPing1.Timeout := 1;
Try
ipwPing1.PingHost(ServerIp);
Except
Result := False;
end;
end;
#29
我提供的解决方案里面的timer2,timer3都是我的系统的业务逻辑,你不必关心