数据库连接失败时,如何捕捉错误,避免弹出错误提示,以便下次自动重新连接
主要是要避免人工介入。一旦弹出错误提示,如果没有人工介入把它关掉,则程序会一直停在那里,无法自动重新连接。
在连接的时候虽然加入了try....except保护,但还是无法避免在操作数据库中数据时网络连接突然断掉或数据库服务被关闭时弹出错误提示。
曾经看到过可以在Application的某个事件中进行处理,但现在检索不到
[解决办法]
LZ说的那个事件是Applicataion.OnException,程序所有错误都会触发这个事件
一个系统和数据库连接的代码可能有很多,又存在于不同的单元
每个open/excesql/...都加上try...except显然不好实现,自己想办法写一个方法能通用的,然后供其它的单元调用
然后只在此方法内try...except就行了,连接失败就锁定程序再启动检测,多长时间或者多少次也连接不成功就退出程序,不过要区别是SQL语句语法错误还是ADO连接失败,可以再嵌套一个try...except,如:
- Delphi(Pascal) code
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:=‘’;通过返回值可以处理是否需要重新连接数据库,给你一段代码看看:
- Delphi(Pascal) code
{初始化时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;