测试ADO连接并重新执行之前,在VBScript

问题描述:

我有下面的VBScript(VBS):测试ADO连接并重新执行之前,在VBScript

Option Explicit 

Dim cn, cmDB, rs 
Set cn = CreateObject("ADODB.Connection") 

cn.ConnectionString = "DSN=PostgreSQLDNSHere" 
cn.Open 
cn.CommandTimeout = 28800 
Set cmDB = CreateObject("ADODB.Command") 
cmDB.CommandTimeout = 28800 

Set rs = CreateObject("ADODB.Recordset") 
rs.CursorType = 2 

MsgBox "disconnected network here then clicked ok to proceed" 
MsgBox cn.State 
MsgBox cmDB.State 
MsgBox rs.State 

Set rs = cn.Execute("select * from test;") 

WScript.Quit 

在第一个消息框,我想模拟输给我们的数据库的连接。可能的原因可能是数据库关闭或局域网关闭等。换句话说,我想测试连接是否正常,所以有效的执行语句会成功。上面的msgboxes在从网络断开连接后永远不会改变。

我目前可以做的唯一方法是在On Error Resume Next之后Execute,然后看Err.Number。有没有一种方法来测试之前执行的连接这样我就可以重新再execute这样的:

Option Explicit 

Dim cn, cmDB, rs 
Set cn = CreateObject("ADODB.Connection") 

cn.ConnectionString = "DSN=PostgreSQLDNSHere" 
cn.Open 
cn.CommandTimeout = 28800 
Set cmDB = CreateObject("ADODB.Command") 
cmDB.CommandTimeout = 28800 

Set rs = CreateObject("ADODB.recordset") 
rs.CursorType = 2 

MsgBox "disconnected network here then clicked ok to proceed" 

If cn.State = ?? Then 
    'reconnect here 
End If 
Set rs = cn.Execute("select * from test;") 

WScript.Quit 

EDIT1: 我也试着设置断开后的记录,但这并没有改变消息框结果在第一个代码片段中。

State属性仅指示客户端上的连接状态。 AFAIK您需要执行查询以检测服务器是否仍然可用。

Set cmd = CreateObject("ADODB.Command") 
cmd.ActiveConnection = cn 
cmd.CommandText = "SELECT 1;" 

On Error Resume Next 
Set rs = cmd.Execute 
If Err Then 
    If Err.Number = &h80004005 Then 
    'server side disconnected -> re-open 
    cn.Close 
    cn.Open 
    Else 
    WScript.Echo "Unexpected error 0x" & Hex(Err.Number) & ": " & Err.Description 
    WScript.Quit 1 
    End If 
End If 

请注意,您可能需要将重新打开的连接重新分配给使用它的对象。

还要注意,上面只是通过关闭和重新打开连接来进行最基本的重新连接。在真实情况下,如果重新连接失败(例如,因为网络或服务器尚未恢复),您可能希望能够重试至少几次。

+0

谢谢!我添加了另一个符合你的建议的答案。如果你想从这个答案中清理我的代码并放入你的答案,请随时取消我的答案。 – mountainclimber

使用Ansgar的建议我发布的代码将“至少尝试几次”。该函数将返回连接对象,如果它成功地重新连接或尝试的时间的用户输入号码和等待尝试之间的秒的用户输入号码后,连接已经是很好的,否则nothing

Option Explicit 

dim cn, cmDB, rs 
set cn = CreateObject("ADODB.Connection") 

cn.ConnectionString= "DSN=PostgreSQLDsn" 
cn.open 
cn.CommandTimeout = 28800 
Set cmDB = CreateObject("ADODB.Command") 
cmDB.CommandTimeout = 28800 

set rs = CreateObject("ADODB.recordset") 
rs.CursorType = 2 

msgbox "disconnected internet here then clicked ok to proceed"  

set cn = TestReOpenConnection(cn,"DSN=PostgreSQLDsn",28800,2,100) 

if cn is nothing then 
    msgbox "not good" 
    WScript.Quit 
end if 

set rs = cn.execute("select * from test;") 
msgbox "all good: " & rs.fields("x") 

WScript.Quit 

function TestReOpenConnection(cn,sDsn,iConnTimeOut,iWaitSecs,iTimesToTry) 

    dim iWaitMilSecs 
    iWaitMilSecs = iWaitSecs * 1000 
    dim bConnected 
    bConnected = false 
    dim iTries 
    iTries = 0 
    dim rsTest 
    set rsTest = CreateObject("ADODB.recordset") 

    do while bConnected = false 

     On Error Resume Next 

     Set rsTest = cn.execute("select 1;") 
     If Err Then 

      if iTries <> 0 then 
       WScript.Sleep iWaitMilSecs 'if we tried once already, then wait 
      end if 

      cn.Close 
      set cn = CreateObject("ADODB.Connection") 
      cn.ConnectionString= sDsn 

      On Error Resume Next 
      cn.open 
      cn.CommandTimeout = iConnTimeOut 
     else 

      bConnected = true 
      set TestReOpenConnection = cn 
     End If 
     iTries = iTries + 1 
     if iTries > iTimesToTry then 
      set TestReOpenConnection = nothing 
      exit do 
     end if 
    loop 

end function 

这个答案ISN”对我所问的核心问题来说是必要的,但我认为这对将来查看这个问题的人有用。可能可以使用一些清理。