data module的oncreate事件中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;
在进销存中如果网线断网后再刷新会提示连接失败,如果网络正常后也要退出整个程序后才能再进入操作,刷新也没用
有些程序可以实现重新连接,如何实现呢

解决方案 »

  1.   

    搞个TIMER控件,隔段时间检查一下是否连接正常,如果断开了,再执行一次连接代码 !
      

  2.   

    把里面的 KeepConnection 属性给 False 了以后用一次连一次
      

  3.   

      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;
     还是不行
      

  4.   

    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;
    都可以,不过太影响速度了,有没有简单点办法
      

  5.   

    这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
    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;
      

  6.   

    在执行操作前,判断一下adoconnection是否联接正常。
      

  7.   

    不需要吧
    如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的
      

  8.   

    这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。解决方法:
    在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。楼主可以试试。
      

  9.   

    你像我一样把检测代码放在时钟里执行嘛,这样的话,当网络重新连通后,ADOConnection就会在后台悄悄重连了
      

  10.   

    @xuxugr, @ahhjgh
    只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。
      

  11.   


    用time事件,你是每多少时间检测一次,而且这样话是不是非常影响速度呢,耗用服务器资源呢
      

  12.   

    几秒检测一次,因为重连之前,我是先PING服务器的,如果不通的话,就不会去打开ADOCONNECTION,所以不会耗费服务器资源的,也基本不耗费客户端资源,整个过程不会产生检测延时,造成假死的现象
      

  13.   

    这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以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.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的
      

  14.   

    在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用
      

  15.   

    这个方法比较耗费资源,并且会造成假死现象,因为:
    1、当网络正常时,这种方法还是会频繁查询数据库,造成资源浪费;
    2、当网络断开时,该方法会造成假死现象,首先调用canlink时,因为网络不通,会有延时等待,并且必定返回FALSE,这时又会去重连数据库,又会造成更大的延时等待。检测、重连循环进行,不断的假死,直到网络正常为止
      

  16.   

    to ahhigh  你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒. 另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?  
      

  17.   

    data module没有time事件呀,难道在进入系统的主窗体再做一个
      

  18.   


    当数据库连接成功后,如果KeepConnection=True,那碰到连接断开时Connected属性仍未True。这个时候可以在OnExecuteComplete里面可以调用Close把Connection关闭。我的意思是根据网络情况适当调整ConnectionTimeout和CommandTimeout的值,来减少超时时间。这对于采用同步连接的ADO来说,永远无法避免,使用Timer也是如此。
      

  19.   


    ahhjigh你能把form1,form2里的源代码全部发给我吗,麻烦你了,我是新手
    [email protected]
      

  20.   

    我就不相信delphi没有好的解决方法吗
      

  21.   

    使用IPWORKS 控件实现PINGSERVER函数
    function TForm2.PingServer(ServerIp:string):boolean;
    begin
      Result := True;
      ipwPing1.Timeout := 1;
      Try
        ipwPing1.PingHost(ServerIp);
      Except
        Result := False;
      end;
    end;
      

  22.   

    我提供的解决方案里面的timer2,timer3都是我的系统的业务逻辑,你不必关心