Delphi:ADOConnection连接SQLServer自动断网问题解决
生活随笔
收集整理的這篇文章主要介紹了
Delphi:ADOConnection连接SQLServer自动断网问题解决
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
===============================
解決方法一:異常時(shí)關(guān)閉連接,WinXP,win7 32位大部分情況都是起作用的,不過(guò)在有些windows操作系統(tǒng)下(如家庭版)不起作用,不知為何?
===============================
?
try
//執(zhí)行sql操作
except
AdoConnection.close;//出現(xiàn)異常時(shí)關(guān)閉連接,在執(zhí)行sql語(yǔ)句時(shí)會(huì)自動(dòng)打開(kāi)連接,從而實(shí)現(xiàn)斷線重連
end;
?
?
===============================
解決方法二:ADO控件動(dòng)態(tài)創(chuàng)建,獨(dú)立設(shè)置連接字符串,為了避免連接不上時(shí)界面卡死,可以考慮放到線程中執(zhí)行。
推薦,親測(cè)有效
===============================
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連接獲取數(shù)據(jù)線程TAdoThread = class(TThread)protectedprocedure execute; override;end; varFrmMain: TFrmMain;ConString: string;{ 初始化臨界區(qū)CS變量 }CS: TRTLCriticalSection; implementationuses untabout;{$R *.dfm}{ TForm1 }{ 寫(xiě)程序異常日志 } procedure write_error_log(str: string); varF: TextFile;mfile: string; begintry//判斷保存日志文件的目錄是否存在if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'log') thenMkDir(ExtractFilePath(ParamStr(0)) + 'log');//按日期及時(shí)間設(shè)定保存日志的文件名mfile := ExtractFilePath(ParamStr(0)) + 'log\ErrLog_' + formatdatetime('yyyy-mm-dd', now) + '.txt';AssignFile(F,mfile);if not FileExists(mfile) thenRewrite(F);//如果文件不存在,則創(chuàng)建一個(gè)新的文件,并寫(xiě)入Append(F); //追加寫(xiě)入Writeln(F,str);//寫(xiě)入并換行 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);//初始化線程臨界區(qū)
end;procedure TFrmMain.Timer2Timer(Sender: TObject); beginTimer2.Enabled := False;TAdoThread.Create(False); end; procedure TFrmMain.getXXData(); varADOStoredProc1: TADOStoredProc; beginADOStoredProc1 := TADOStoredProc.Create(nil);//動(dòng)態(tài)創(chuàng)建ADO控件trytryADOStoredProc1.ConnectionString := ConString;//采用獨(dú)立的連接字符串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)+ '>> 執(zhí)行g(shù)etXXData時(shí)發(fā)生異常!錯(cuò)誤原因:'+E.Message);end;endfinallyADOStoredProc1.Free;end; end;{ TAdoThread } procedure TAdoThread.execute; begininherited;FreeOnTerminate := True; //設(shè)置線程執(zhí)行完成后自動(dòng)釋放{進(jìn)入線程臨界區(qū)}EnterCriticalSection(CS);tryCoInitialize(nil); //線程中使用ADO,必須調(diào)用(需Uses ActiveX){讀取HIS數(shù)據(jù)}FrmMain.getHisData(FrmMain.hasCharge);CoUninitialize;finally{ 離開(kāi)線程臨界區(qū) }LeaveCriticalSection(CS);end;FrmMain.Timer2.Enabled := True; end;end.
============================
其他解決方法:未驗(yàn)證,資料來(lái)自:
http://bbs.csdn.net/topics/390958648
============================
Win7上ADO連接SQLServer過(guò)幾十分鐘后自動(dòng)斷網(wǎng)(被防火墻攔截等)問(wèn)題終于解決了,困惑了很久
今天終于解決了!方法很簡(jiǎn)單,和大家共享一下。
問(wèn)題現(xiàn)象:ADO連接SQLServer過(guò)幾十分鐘后(有的過(guò)幾周)數(shù)據(jù)庫(kù)連接無(wú)緣無(wú)故斷開(kāi),
再做數(shù)據(jù)庫(kù)操作報(bào)錯(cuò)“連接失敗”。實(shí)際上此時(shí)數(shù)據(jù)庫(kù)服務(wù)器可以ping通,
新創(chuàng)建其他ADO控件連接數(shù)據(jù)庫(kù)也沒(méi)問(wèn)題。就這個(gè)ADO不行了。
問(wèn)題分析:
剛開(kāi)始想得比較簡(jiǎn)單,只要?jiǎng)?chuàng)建個(gè)線程或者Timer時(shí)時(shí)判斷ADOConnecton1.Active屬性=false不得了么。但實(shí)際上因?yàn)楹笈_(tái)原因
或者服務(wù)斷開(kāi)再重連、被防火墻攔截等意外情況發(fā)生時(shí)ADOConnecton1.Active屬性仍然是true!無(wú)法判斷。
后來(lái)想到用ping,如果ping不通那就斷開(kāi)了?!但是ping通了未必說(shuō)明數(shù)據(jù)庫(kù)就能連通!ping無(wú)法判斷數(shù)據(jù)庫(kù)能否連通。
那么線程里面不斷執(zhí)行個(gè)select?GetDate?之類(lèi)簡(jiǎn)單SQL,如果失敗就判斷數(shù)據(jù)庫(kù)斷開(kāi)行不行呢?顯然不行,
多用戶(hù)同時(shí)不斷連接數(shù)據(jù)庫(kù)對(duì)服務(wù)器壓力太大了,不可取。
后來(lái)網(wǎng)上查了很多材料,有人提出捕獲OleException的方法,既不創(chuàng)建線程和定時(shí)器判斷數(shù)據(jù)庫(kù)是否斷開(kāi),而是當(dāng)用戶(hù)執(zhí)行操作
發(fā)生Ole異常時(shí)捕獲它,如果是數(shù)據(jù)庫(kù)連接錯(cuò)誤,那么恢復(fù)數(shù)據(jù)庫(kù)連接即可,我在他們代碼基礎(chǔ)上完善了一下,以下是實(shí)現(xiàn)代碼。
控件:
????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
??//請(qǐng)執(zhí)行如下命令或者其他方法強(qiáng)制產(chǎn)生數(shù)據(jù)庫(kù)連接斷開(kāi)情況,以觸發(fā)如下異常。
??//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('重連數(shù)據(jù)庫(kù)發(fā)生錯(cuò)誤:'#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;
?
轉(zhuǎn)載于:https://www.cnblogs.com/tc310/p/5133505.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Delphi:ADOConnection连接SQLServer自动断网问题解决的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PHP API接口GETPOST请求封装
- 下一篇: 数据库——环境初建改端口和密码(转)