检查SQL Server服务器可用性的最快方法是什么?

时间:2010-01-28 16:50:13

标签: sql-server ms-access vba

我在多个位置使用MS Access程序。它连接到MS SQL Server表,但每个位置的服务器名称不同。我正在寻找测试服务器存在的最快方法。我目前使用的代码如下所示:

ShellWait "sc \\" & ServerName & " qdescription MSSQLSERVER > " & Qt(fn)
FNum = FreeFile()
Open fn For Input As #FNum
Line Input #FNum, Result
Close #FNum
Kill fn

If InStr(Result, "SUCCESS") Then ...

ShellWait:执行shell命令并等待它完成
Qt:用双引号包装一个字符串
fn:临时文件名变量

我针对服务器名称列表运行上述代码(其中只有一个通常可用)。如果服务器可用,代码大约需要一秒钟,对于每个不可用的服务器大约需要8秒。如果可能的话,我希望将这两者降低,但特别是失败的情况,因为这种情况最常发生。

6 个答案:

答案 0 :(得分:2)

您可以尝试创建ADO连接并将超时设置为某个较低的值,例如(另):

Dim cn As ADODB.Connection 
Set cn = New ADODB.Connection
cn.ConnectionTimeout = 4     ' Wait at most 4 seconds for connection
cn.ConnectionString = "Provider=SQLOLEDB.1;Data Source=" & ServerName & ";Integrated Security=SSPI"

On Error Resume Next
cn.Open
If Err.Number > 0 Then
    ...
Else
    cn.Close
    ...
End If
On Error Goto 0   ' replace 0 with previously used error handler

答案 1 :(得分:2)

我最终确定的解决方案是使用nslookup.exe作为我的sc.exe命令的前身。如果SQL Server服务器不存在,nslookup会立即告诉我。进行此更改可将SQL Server查找失败所需的时间从大约8秒减少到大约1秒。成功案例实际上稍长,但并不明显。对于那些可能感兴趣的人,这是我的最终解决方案(希望我的个人功能的目的[ShellWait,Qt,PassThru,LogError]将是显而易见的):

更新:我已经更新了函数,以合并dmaruca的clsRunApp(我最喜欢的类模块)和Philippe提出的关于在断开连接模式下工作的问题。结果比我最初发布的要好得多,我要感谢他们的贡献。这是现在的功能:

Function SQLServerDBExists(ComputerName As String, DbName As String) As Boolean
Const LocalHost = "127.0.0.1"
Dim Result As String, RunApp As New clsRunApp

    On Error GoTo Err_SQLServerDBExists

    If ComputerName <> LocalHost And _
       ComputerName <> "." And _
       ComputerName <> Environ("COMPUTERNAME") Then
        'Check for existence of the server using Name Server Lookup'
        Result = RunApp.RunAppWait_CaptureOutput("nslookup " & ComputerName)
        If InStr(Result, "Non-existent domain") Or _
           InStr(Result, "Default servers are not available") Then
            SQLServerDBExists = False
            GoTo Exit_SQLServerDBExists
        End If
    End If

    Result = RunApp.RunAppWait_CaptureOutput("sc \\" & ComputerName & " qdescription MSSQLSERVER")
    If InStr(Result, "SUCCESS") Then
        With PassThru("SELECT Name FROM sysdatabases " & _
                      "WHERE Name='" & DbName & "'", "master", ComputerName)
            SQLServerDBExists = (Not .EOF)
        End With
    End If

Exit_SQLServerDBExists:
    Exit Function
Err_SQLServerDBExists:
    LogError Err.Number, Err.Description, "SQLServerDBExists", "AttachToSQL"
    Resume Exit_SQLServerDBExists
End Function

注意:我发现Environ(“COMPUTERNAME”)不是确定计算机名称的100%可靠方式,因此如果您愿意,可以随意使用您自己的代码替换它。我认为懒惰的方法足以达到其目的。

答案 2 :(得分:2)

如果我不在线,我很抱歉,因为我是新来的,但我想提出一个建议。实际上,您可以使用windows api捕获带壳命令的输出,而无需使用中间文本文件。我创建了一个小类文件,它可以干净地包装它(link)。

使用此功能,您可以将代码重构为此,而不必担心阅读文件会带来额外的麻烦。

Function SQLServerDBExists(ServerName As String, DbName As String) As Boolean
Dim Result As String
Dim cls as new clsRunApp

On Error GoTo Err_SQLServerDBExists

'Check for existence of the server
Result = cls.RunAppWait_CaptureOutput("nslookup " & ServerName)
If InStr(Result, "Non-existent domain") Then
    SQLServerDBExists = False
    GoTo Exit_SQLServerDBExists
End If

 Result = cls.RunAppWait_CaptureOutput("sc \\" & ServerName & " qdescription MSSQLSERVER")
If InStr(Result, "SUCCESS") Then
    With PassThru("SELECT Name FROM sysdatabases " & _
                  "WHERE Name='" & DbName & "'", "master", ServerName)
        SQLServerDBExists = (Not .EOF)
    End With
End If

Exit_SQLServerDBExists:
    Exit Function
Err_SQLServerDBExists:
    LogError Err.Number, Err.Description, "SQLServerDBExists", "AttachToSQL", , , Erl
    Resume Exit_SQLServerDBExists
End Function

答案 3 :(得分:1)

我这样做的方式(在遥远的过去)是使用链接表并有一个用户表单,允许服务器在运行时一次性选择。或者,您可以将服务器名称放在配置文件中,并使用它动态创建连接字符串。

答案 4 :(得分:1)

telnet servername 1433

答案 5 :(得分:0)

此处提出的解决方案在特定条件下运行良好,其中计算机已联网且dns服务器可用。如果您的应用程序应该在连接(可以连接到其中一个'主'服务器)和断开连接模式(连接到数据库的本地副本)中工作,则此解决方案将不会这样做。

我们的通用,高效但(我必须承认)不那么聪明的解决方案到目前为止还有一个客户端连接表(实际上是xml文件 - 每个连接一个 - 在app文件夹中)并让用户选择启动时的连接。根据用户,他工作的地点以及离线工作的能力,我们可以选择在他的计算机上安装哪些xml连接字符串。

我们的想法是(当我们有时间时)使用计算机的IP地址来识别/计算可用的“最佳”数据库服务器:如果计算机没有联网,则连接将设置为“localhost”。否则,将在数据库服务器被赋予预定义IP后缀的网络上“即时”建立连接。因此,当计算机的ip是aaa.bbb.ccc.ddd时,机器将知道它必须连接到aaa.bbb.120.132,其中120.132是预定义的数据库服务器后缀。