数据库连接失败时,如何捕捉错误,避免弹出错误提示,以便下次自动重新连接

数据库连接失败时,如何捕捉错误,避免弹出错误提示,以便下次自动重新连接

主要是要避免人工介入。一旦弹出错误提示,如果没有人工介入把它关掉,则程序会一直停在那里,无法自动重新连接。 
在连接的时候虽然加入了try....except保护,但还是无法避免在操作数据库中数据时网络连接突然断掉或数据库服务被关闭时弹出错误提示。 
曾经看到过可以在Application的某个事件中进行处理,但现在检索不到

LZ说的那个事件是Applicataion.OnException,程序所有错误都会触发这个事件

一个系统和数据库连接的代码可能有很多,又存在于不同的单元
每个open/excesql/...都加上try...except显然不好实现,自己想办法写一个方法能通用的,然后供其它的单元调用

然后只在此方法内try...except就行了,连接失败就锁定程序再启动检测,多长时间或者多少次也连接不成功就退出程序,不过要区别是SQL语句语法错误还是ADO连接失败,可以再嵌套一个try...except,如:

  try
  adoquery1.open;
  except
    on e:exception do
    begin
      showmessage('执行语句失败,原因:'+e.message);
      try
        adoconnection1.Connected:=false;
        adoconnection1.Connected:=true;
      except
        on e:exception do
        begin
          {showmessage('连接数据库失败,原因:'+:e.message);
          这里调用另一方法启动检测(方法内是循环/延时}
        end;
      end;
    end;
  end;
 
 
这种情况应该在有数据库操作的函数中处理,通过try except  end来扑捉数据库连接错误消息,如果数据库操作有错误或者连接失败,
则rusult:=e.message ,如果没有错误则result:=‘’;通过返回值可以处理是否需要重新连接数据库,给你一段代码看看:
 
{初始化时Timer的enable为false}
procedure TDataModule1.TimerTimer(Sender:TObject);
begin
  OpenLink;  {用户重新连接数据库}
end;
 
procedure TDataModule1.OpenLink;
var
  ini:Tinifile;
  s,DSource,dbname,uname,pword:string;
begin
   Timer.Enabled:=false;
   ledform.label1.Caption:='正在重新连接数据库......';
 
   ini:=Tinifile.Create(extractfilepath(paramstr(0))+'DataConnect.ini');
   try
     DSource:=ini.ReadString('DataBase','Server','192.168.0.1');
     dbname:=ini.ReadString('DataBase','DB','Message');
     uname:=ini.ReadString('DataBase','UName','user');
     pword:=ini.ReadString('DataBase','PW','12345');
   finally
     ini.Free;
   end;
   s:='Provider=SQLOLEDB.1;Persist Security Info=True;';
   s:=s+'Data Source='+DSource;
   s:=s+';User ID='+uname;
   s:=s+';Password='+pword;
   s:=s+';Initial Catalog='+dbname;
 
   try
     ADOConnection1.Close;
     ADOConnection1.ConnectionString:=s;
     ADOConnection1.Open;
     ledform.label1.Visible:=false;
   except
     ledform.label1.Caption:=‘连接数据库失败!10秒后重试!';
     Timer.Interval:=10000;
     Timer.Enabled:=true;
   end
end;
 
{数据库操作}
function TDataModule1.GetSD(Sid: Integer;ppn:Integer):string;
begin
  try
    with WSD do
    begin
      Close;
      SQL.Clear ;
      SQL.Add('select * from led_kongtiao_View');
      SQL.Add(' where ITEM_ID='+inttostr(Sid));
      Open;
 
      if RecordCount>0 then
      begin
        if (FieldByName('ITEM_VALUE').IsNull) or (FieldByName('ITEM_VALUE').AsString=''then
           SD[ppn]:='---'
        else
          SD[ppn]:=Dl(FieldByName('ITEM_VALUE').AsFloat)+'%';
      end;
    end;
  except
    on E: Exception do
      Result := E.Message;
  end;
end;
 
{判断数据库操作是否成功}
function Tledform.GetDB: string;
var
  str:string;
begin
  Result:='';
  str:=DataModule1.GetSD(1,1);
  if str<>'' then
    {重新连接数据库,具体可根据自己的实际情况来处理!}
    DataModule1.timer.enable:=true;
  else
    {正常连接数据库,无操作}
end;
 
 
 
 
 
 
 
 
  
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/lantianhf/p/6084155.html