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

===============================

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

===============================

try

//执行sql操作

except

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

end;

===============================

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

推荐,亲测有效

===============================

unit untMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  IniFiles, ExtCtrls, DB, ADODB,ActiveX;

type
  TFrmMain = 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)
  protected
    procedure execute; override;
  end;
var
  FrmMain: TFrmMain;
  ConString: string;
  { 初始化临界区CS变量 }
  CS: TRTLCriticalSection;
implementation

uses untabout;

{$R *.dfm}

{ TForm1 }{ 写程序异常日志 }
procedure write_error_log(str: string);
var
  F: TextFile;
  mfile: string;
begin
  try
    //判断保存日志文件的目录是否存在
    if not DirectoryExists(ExtractFilePath(ParamStr(0)) + ‘log‘) then
      MkDir(ExtractFilePath(ParamStr(0)) + ‘log‘);

    //按日期及时间设定保存日志的文件名
    mfile := ExtractFilePath(ParamStr(0)) + ‘log\ErrLog_‘ + formatdatetime(‘yyyy-mm-dd‘, now) + ‘.txt‘;

    AssignFile(F,mfile);
    if not FileExists(mfile) then
      Rewrite(F);//如果文件不存在,则创建一个新的文件,并写入
    Append(F); //追加写入
    Writeln(F,str);//写入并换行
    CloseFile(F);
  except
  end;
end;
procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  { 清除线程CS变量 }
  DeleteCriticalSection(CS);
  Timer2.Enabled := False;
end;
procedure TFrmMain.FormShow(Sender: TObject);
var
  clientini: TIniFile;
  db_server,user,password:string;
begin
  { 获取ini配置信息}
  clientini := TIniFile.Create(‘.\config.ini‘);
  try
    if clientini<>nil then
    begin
      db_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;
  finally
    clientini.Free;
  end;
  InitializeCriticalSection(CS);//初始化线程临界区

end;

procedure TFrmMain.Timer2Timer(Sender: TObject);
begin
  Timer2.Enabled := False;
  TAdoThread.Create(False);
end;
procedure TFrmMain.getXXData();
var
  ADOStoredProc1: TADOStoredProc;
begin
  ADOStoredProc1 := TADOStoredProc.Create(nil);//动态创建ADO控件
  try
    try
      ADOStoredProc1.ConnectionString := ConString;//采用独立的连接字符串
      if ADOStoredProc1.Active then
         ADOStoredProc1.Active := false;
      ADOStoredProc1.ProcedureName := ‘GetData‘;
      ADOStoredProc1.Prepared := false;
      ADOStoredProc1.Parameters.Refresh;
      ADOStoredProc1.Prepared := true;
      ADOStoredProc1.ExecProc;
    except
      on E:Exception do
      begin
        write_error_log(FormatDateTime(‘yyyy-mm-dd hh:nn:ss‘,Now)
          + ‘>> 执行getXXData时发生异常!错误原因:‘+E.Message
          );
      end;
    end
  finally
    ADOStoredProc1.Free;
  end;
end;

{ TAdoThread }
procedure TAdoThread.execute;
begin
  inherited;
  FreeOnTerminate := True; //设置线程执行完成后自动释放
  {进入线程临界区}
  EnterCriticalSection(CS);
  try
    CoInitialize(nil); //线程中使用ADO,必须调用(需Uses ActiveX)
    {读取HIS数据}
    FrmMain.getHisData(FrmMain.hasCharge);
    CoUninitialize;
  finally
    { 离开线程临界区 }
    LeaveCriticalSection(CS);
  end;
  FrmMain.Timer2.Enabled := True;
end;

end.

============================
其他解决方法:未验证,资料来自:
http://bbs.csdn.net/topics/390958648
============================
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;

原文地址:https://www.cnblogs.com/jijm123/p/10128811.html

时间: 2024-12-09 09:05:33

Delphi:ADOConnection连接SQLServer自动断网问题解决的相关文章

Mac系统之 ---- 解决Mac OS X 10.8 休眠 WiFi 自动断网问题

自从OS X 10.8 发布一来一直有个小问题就是长时间不使用的时候系统会自动进入休眠状态并且断开wifi网络连接.这样会造成下载的数据暂停等. 有些小不方便. 经过搜索, 可以在终端内输入如下命令暂停这个休眠. 新版的支持一个Standby的模式的,在GUI界面是看不见的,也没有休眠的设置,所以需要使用命令. sudo pmset -a standby 0 sleep 20 hibernatemode 3 networkoversleep 0 force 要恢复只需要在终端输入 sudo pm

笔记本电脑连接wifi有时候会自动断网提示有限的访问权限解决办法

解决办法如下: [设备管理器],找到[网络适配器]第一项,右键属性

Ubuntu服务器断网问题解决

原因:dns服务器没有了配置信息. 配置dns服务器 ubuntu 的dns服务器信息,放在 /etc/resolv.conf中, 添加dns服务器地址,如192.168.1.1,则在上述文件中加入 nameserver 192.168.1.1 [email protected]:/etc/network# cd ..[email protected]:/etc# cat resolv.conf # Generated by NetworkManagernameserver 192.168.1.

公司突然断网故障排查

记一次公司断网故障排查 本来大周一挺好的,刚坐在工位上不到半个小时,公司突然断网,此时,我是有点凌乱的! 下边是排查故障的过程 1,首先我看下本机电脑的IP地址,禁用启动,发现仍旧可以获取到IP地址,这代表DHCP分发是没问题的,因为是突然断网,代表着交换机路由器配置不可能出问题 2,接着我带着笔记本进入机房,看了下光猫,光猫状态正常,然后看了下路由器,路由器是H3C的,有web管理界面,进入web管理界面,发现IP地址状态也是正常的. 4,接着给公司网络运营商打电话,他说是他们那边的问题,有个

MACBOOK 总是断网怎么办

MACBOOK 连接 wifi 老是断网.焦躁不安 看图,二个方法,第一就搞定,?? 留存一份.

Vmware使用Linux系统-_-断网解决方案

今天用Linux系统手贱 去点击网络设置 关闭有线连接 之后出现断网这个情况,写下解决方案 点错了 瞎加了配置,还关了连接. 点击->编辑->虚拟网络编辑器->直接还原默认 这招挺管用的 hahaha... 之后配置文件找不到在那里删除,baidu了下 附上文件地址 这个就是文件的地址,多出来的直接删 原文地址:https://www.cnblogs.com/yanshi3/p/10351163.html

bat实现监测计算机网络连接,断网自动重启网络连接

十月一体验了windows 10预览版之后,决定继续装回正式版,尝个鲜就好了,毕竟预览版还是不稳定,环境不是很方便. 决定装个最新正式版windows 8.1,结果问题来了,无线连接总是失败,显示网络连接受限,断开连接,重新连接就好了.过一会就又断了.... 网上搜了各种办法,有说无线驱动兼容性问题的,换了官网最新驱动,无效.有说设置固定IP的,固定IP,无效.有说勾掉win8"允许计算机关掉此设备以节约电源"的,照做,无效... 各种方法都试了,都无效. 简直点燃了我的小爆脾气.决定

dubbo连接zookeeper注册中心因为断网导致线程无限等待问题

最近维护的系统切换了网络环境,由联通换成了电信网络,因为某些过滤规则导致系统连不上zookeeper服务器(应用系统机器在深圳,网络为电信线路,zookeeper服务器在北京,网络为联通线路),因为我不是运维人员也不懂运维相关的技术,所以排查了很久也不知道原因,最后无奈之下把深圳这边的网络切回了联通,系统恢复正常. 但是因为本次事故体现了一个很严重的问题,即当zookeeper注册中心连不上时dubbo的线程会无限等待,因为系统有一些定时任务会比较频繁地开启新线程连接dubbo,所以导致的结果是

Android利用广播监听设备网络连接(断网)的变化情况

MainActivity如下: package cc.testnetworkchange; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 利用广播监听设备网络连接的变化情况 * 亦可借此监测到设备是否已经断开网络 */ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedI