ADOConnection连接SQLServer自动断网问题解决

解决方法一:异常时关闭连接,WinXP,win7 32位大部分情况都是起作用的,不过在有些windows操作系统下(如家庭版)不起作用,不知为何?

try

//执行sql操作

except

AdoConnection.close;//出现异常时关闭连接,在执行sql语句时会自动打开连接,从而实现断线重连

end;

 

解决方法二:ADO控件动态创建,独立设置连接字符串,为了避免连接不上时界面卡死,可以考虑放到线程中执行。

推荐,亲测有效

unit untMain;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,IniFiles, ExtCtrls, DB, ADODB,ActiveX;

typeTFrmMain = class(TForm)Timer2: TTimer;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);procedure Timer2Timer(Sender: TObject);private{ Private declarations }
  public{ Public declarations }procedure getXXData();
end;//ADO连接获取数据线程TAdoThread = class(TThread)protectedprocedure execute; override;end;
varFrmMain: TFrmMain;ConString: string;{ 初始化临界区CS变量 }CS: TRTLCriticalSection;
implementationuses untabout;{$R *.dfm}{ TForm1 }{ 写程序异常日志 }
procedure write_error_log(str: string);
varF: TextFile;mfile: string;
begintry//判断保存日志文件的目录是否存在if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'log') thenMkDir(ExtractFilePath(ParamStr(0)) + 'log');//按日期及时间设定保存日志的文件名mfile := ExtractFilePath(ParamStr(0)) + 'log\ErrLog_' + formatdatetime('yyyy-mm-dd', now) + '.txt';AssignFile(F,mfile);if not FileExists(mfile) thenRewrite(F);//如果文件不存在,则创建一个新的文件,并写入Append(F); //追加写入Writeln(F,str);//写入并换行
    CloseFile(F);exceptend;
end;
procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin{ 清除线程CS变量 }DeleteCriticalSection(CS);Timer2.Enabled := False;
end;
procedure TFrmMain.FormShow(Sender: TObject);
varclientini: TIniFile; db_server,user,password:string;
begin{ 获取ini配置信息}clientini := TIniFile.Create('.\config.ini');tryif clientini<>nil thenbegindb_server := trim(clientini.readString('database','db_server',''));user := trim(clientini.readString('database','user','sa'));password := trim(clientini.readString('database','password',''));
ConString := 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID='+user+';Password='+password+';Initial Catalog=Testdb;Data Source='+db_server;
    end;finallyclientini.Free;end;InitializeCriticalSection(CS);//初始化线程临界区

end;procedure TFrmMain.Timer2Timer(Sender: TObject);
beginTimer2.Enabled := False;TAdoThread.Create(False);  
end;
procedure TFrmMain.getXXData();
varADOStoredProc1: TADOStoredProc;
beginADOStoredProc1 := TADOStoredProc.Create(nil);//动态创建ADO控件trytryADOStoredProc1.ConnectionString := ConString;//采用独立的连接字符串if ADOStoredProc1.Active thenADOStoredProc1.Active := false;ADOStoredProc1.ProcedureName := 'GetData';ADOStoredProc1.Prepared := false;ADOStoredProc1.Parameters.Refresh;ADOStoredProc1.Prepared := true;ADOStoredProc1.ExecProc;excepton E:Exception dobeginwrite_error_log(FormatDateTime('yyyy-mm-dd hh:nn:ss',Now)+ '>> 执行getXXData时发生异常!错误原因:'+E.Message);end;endfinallyADOStoredProc1.Free;end; 
end;{ TAdoThread }
procedure TAdoThread.execute;
begininherited;FreeOnTerminate := True; //设置线程执行完成后自动释放{进入线程临界区}EnterCriticalSection(CS);tryCoInitialize(nil); //线程中使用ADO,必须调用(需Uses ActiveX){读取HIS数据}FrmMain.getHisData(FrmMain.hasCharge);CoUninitialize;finally{ 离开线程临界区 }LeaveCriticalSection(CS);end;FrmMain.Timer2.Enabled := True;
end;end.

 

Win7上ADO连接SQLServer过几十分钟后自动断网(被防火墙拦截等)问题终于解决了,困惑了很久
今天终于解决了!方法很简单,和大家共享一下。

问题现象:ADO连接SQLServer过几十分钟后(有的过几周)数据库连接无缘无故断开,
再做数据库操作报错“连接失败”。实际上此时数据库服务器可以ping通,
新创建其他ADO控件连接数据库也没问题。就这个ADO不行了。

问题分析:
刚开始想得比较简单,只要创建个线程或者Timer时时判断ADOConnecton1.Active属性=false不得了么。但实际上因为后台原因
或者服务断开再重连、被防火墙拦截等意外情况发生时ADOConnecton1.Active属性仍然是true!无法判断。
后来想到用ping,如果ping不通那就断开了?!但是ping通了未必说明数据库就能连通!ping无法判断数据库能否连通。
那么线程里面不断执行个select GetDate 之类简单SQL,如果失败就判断数据库断开行不行呢?显然不行,
多用户同时不断连接数据库对服务器压力太大了,不可取。
后来网上查了很多材料,有人提出捕获OleException的方法,既不创建线程和定时器判断数据库是否断开,而是当用户执行操作
发生Ole异常时捕获它,如果是数据库连接错误,那么恢复数据库连接即可,我在他们代码基础上完善了一下,以下是实现代码。

控件:

    Button1: TButton;
    ADOConnection1: TADOConnection;
    Button2: TButton;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    ApplicationEvents1: TApplicationEvents;
uses ComObj;

{$R *.dfm}

procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
  I: integer;
begin
  //请执行如下命令或者其他方法强制产生数据库连接断开情况,以触发如下异常。
  //net stop MsSqlServer
  //net start MsSqlServer
  if (E is EOleException) and ((E as EOleException).ErrorCode= -2147467259) then
  begin
    ADOConnection1.Connected := False;
    try
      ADOConnection1.Connected := True;
    except On E2: Exception do
    begin
      MessageDlg('重连数据库发生错误:'#13 + E2.Message, mtError, [mbOK], 0);
    end;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sSQL: string;
begin
  sSQL:= 'Provider=SQLOLEDB.1;Password=YourPassword;Persist Security Info=True;' +
    'User ID=sa;Initial Catalog=YourDatabase;Data Source=.';

  with ADOConnection1 do
  begin
    LoginPrompt:= false;
    Connected:= false;
    ConnectionString:= sSQL;
    Connected:= true;
  end;
  ShowMessage('ok');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  with ADOQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('select * from Test');
    Open;
  end;
end;

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值