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

6

如何检查SQL服务器是否存在?

我正在尝试使用Microsoft.SqlServer.Management.Smo.Server.PingSqlServerVersion(),如果服务器存在且可用,则可以正常工作。但是,如果没有这样的服务器,它会变得相当缓慢。

是否有足够快速的方法来检查服务器是否存在,而无需定义用户凭据(仅服务器名称)?

您推荐使用什么方法?


这有什么用处?在什么情况下,有人会部署一个数据库应用程序,却不知道是否存在数据库? - mikerobi
我们确实需要知道一个响应缓慢的服务器被视为不可用的程度。 - Richard
5个回答

5
你仍然可以使用 Microsoft.SqlServer.Management.Smo.Server.PingSqlServerVersion(),但需要异步使用。例如,你可以通过BackWorker类来调用它。在 DoWork 事件中调用 Microsoft.SqlServer.Management.Smo.Server.PingSqlServerVersion(),而 RunWorkerCompleted 只需将一个布尔变量设置为 true。这样,你就可以发起请求,等待任意长时间,检查布尔值,如果不为 true,则说明 SQL server 尚未响应,你可以取消 BackgroundWorker。

4
您可以使用TcpClient类查询服务器并检查特定端口是否打开,代码如下所示:

TcpClient 类可用于此目的。

using System.Net;
using System.Net.Sockets;

public bool CheckServerAvailablity(string serverIPAddress, int port)
{
  try
  {
    IPHostEntry ipHostEntry = Dns.Resolve(serverIPAddress);
    IPAddress ipAddress = ipHostEntry.AddressList[0];

    TcpClient TcpClient = new TcpClient();
    TcpClient.Connect(ipAddress , port);
    TcpClient.Close();

    return true;
  }
  catch
  {
    return false;
  }
} 

对于默认实例,这对我很有效,但对于非默认实例则失败了。我发现了这个解决方案,并且可以适用于所有情况:http://www.codeproject.com/Articles/612751/Check-that-Sql-Server-exists-prior-to-connection - Toolsmythe

3
你可以尝试打开一个TCP套接字连接到1433端口(默认SQL端口),并设置短暂的超时时间,看看是否有响应。

这需要启用SQL服务器的TCP/IP协议。


1

补充Mikael的建议,您还可以先ping主机,如果服务器宕机,这将最快地响应。

当然,这一切都假设您正在尝试通过TCP/IP连接到远程服务器。


0

在使用Ben Robinson的答案后,我想出了这个方法,并且对我来说效果很好。 我之前是在try块中使用连接字符串来打开和关闭连接,但是当我在Windows 8.1上运行时,异常从未被捕获,程序崩溃了。

public unsafe bool OdbcConnectionTest(string sConnectionString
    , out int actualTimeMs)
{
    DateTime dtme = DateTime.Now;
    OdbcConnectionStringBuilder con;
    Microsoft.SqlServer.Management.Smo.Server svr;
    Microsoft.SqlServer.Management.Common.ServerVersion sVer;
    Microsoft.SqlServer.Management.Smo.Database db;
    try
    {
        con = new System.Data.Odbc.OdbcConnectionStringBuilder(sConnectionString);
        object sServer;
        if (con.TryGetValue("server", out sServer))
        {
            svr = new Microsoft.SqlServer.Management.Smo.Server((string)sServer);
            if (svr != null)
            {
                sVer = svr.PingSqlServerVersion((string)sServer);
                if (sVer != null)
                {
                    object sDb;
                    if (con.TryGetValue("database", out sDb))
                    {
                        if (!String.IsNullOrWhiteSpace((string)sDb))
                        {
                            db = svr.Databases[(string)sDb];
                            if (db != null && db.IsAccessible)
                            {
                                TimeSpan ts = DateTime.Now - dtme;
                                actualTimeMs = (int)ts.TotalMilliseconds;
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    catch 
    {
        actualTimeMs = -1;
        return false;
    }
    actualTimeMs = -1;
    return false;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接