我在多个位置使用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秒。如果可能的话,我希望将这两者降低,但特别是失败的情况,因为这种情况最常发生。
答案 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是预定义的数据库服务器后缀。