86

我需要开发一个每 5 分钟触发一次的例程,以检查 SQL Server 列表(10 到 12)是否启动并运行。

有没有办法以最少的代码和 sql 操作要求从 C# 中简单地“ping”一个 SQL Server?

4

10 回答 10

92

当服务器停止或暂停连接时,我遇到了 EF 问题,我提出了同样的问题。因此,为了完成上述答案,这里是代码。

/// <summary>
/// Test that the server is connected
/// </summary>
/// <param name="connectionString">The connection string</param>
/// <returns>true if the connection is opened</returns>
private static bool IsServerConnected(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        try
        {
            connection.Open();
            return true;
        }
        catch (SqlException)
        {
            return false;
        }
    }
}
于 2012-03-30T13:23:59.083 回答
82

执行SELECT 1并检查 ExecuteScalar 是否返回 1。

于 2010-03-13T21:22:17.543 回答
14

请参阅 GitHub 上的以下项目:https ://github.com/ghuntley/csharp-mssql-connectivity-tester

try
{
    Console.WriteLine("Connecting to: {0}", AppConfig.ConnectionString);
    using (var connection = new SqlConnection(AppConfig.ConnectionString))
    {
        var query = "select 1";
        Console.WriteLine("Executing: {0}", query);

        var command = new SqlCommand(query, connection);

        connection.Open();
        Console.WriteLine("SQL Connection successful.");

        command.ExecuteScalar();
        Console.WriteLine("SQL Query execution successful.");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Failure: {0}", ex.Message);
}
于 2013-07-09T06:30:02.430 回答
7

不会为您建立与数据库的连接吗?如果数据库未启动,您将无法建立连接。

于 2010-03-13T21:18:00.320 回答
2

对于 Joel Coehorn 的建议,您是否已经尝试过名为tcping的实用程序。我知道这是你没有以编程方式做的事情。它是一个独立的可执行文件,允许您在每个指定的时间间隔 ping。虽然它不在 C# 中。另外..我不确定这是否可行如果目标机器有防火墙..hmmm..

[我对这个网站有点陌生,错误地将其添加为评论,现在将其添加为答案。让我知道这是否可以在这里完成,因为我在这里有重复的评论(作为评论和答案)。我不能在这里删除评论。]

于 2010-03-14T09:07:36.673 回答
2

在端口 1433(默认端口)上查找打开的侦听器。如果在那里创建 tcp 连接后得到任何响应,则服务器可能已启动。


你知道,我第一次写这个是在 2010 年。今天,我只是尝试实际连接到服务器

于 2010-03-13T21:46:11.183 回答
1
public static class SqlConnectionExtension
{
    #region Public Methods

    public static bool ExIsOpen(
        this SqlConnection connection, MessageString errorMsg = null)
    {
        if (connection == null) { return false; }
        if (connection.State == ConnectionState.Open) { return true; }

        try
        {
            connection.Open();
            return true;
        }
        catch (Exception ex) { errorMsg?.Append(ex.ToString()); }
        return false;
    }

    public static bool ExIsReady(
        this SqlConnection connction, MessageString errorMsg = null)
    {
        if (connction.ExIsOpen(errorMsg) == false) { return false; }
        try
        {
            using (var command = new SqlCommand("select 1", connction))
            { return ((int)command.ExecuteScalar()) == 1; }
        }
        catch (Exception ex) { errorMsg?.Append(ex.ToString()); }
        return false;
    }

    #endregion Public Methods
}

public class MessageString : IDisposable
{
    #region Protected Fields

    protected StringBuilder _messageBuilder = new StringBuilder();

    #endregion Protected Fields

    #region Public Constructors

    public MessageString()
    {
    }

    public MessageString(int capacity)
    {
        _messageBuilder.Capacity = capacity;
    }

    public MessageString(string value)
    {
        _messageBuilder.Append(value);
    }

    #endregion Public Constructors

    #region Public Properties

    public int Length {
        get { return _messageBuilder.Length; }
        set { _messageBuilder.Length = value; }
    }

    public int MaxCapacity {
        get { return _messageBuilder.MaxCapacity; }
    }

    #endregion Public Properties

    #region Public Methods

    public static implicit operator string(MessageString ms)
    {
        return ms.ToString();
    }

    public static MessageString operator +(MessageString ms1, MessageString ms2)
    {
        MessageString ms = new MessageString(ms1.Length + ms2.Length);
        ms.Append(ms1.ToString());
        ms.Append(ms2.ToString());
        return ms;
    }

    public MessageString Append<T>(T value) where T : IConvertible
    {
        _messageBuilder.Append(value);
        return this;
    }

    public MessageString Append(string value)
    {
        return Append<string>(value);
    }

    public MessageString Append(MessageString ms)
    {
        return Append(ms.ToString());
    }

    public MessageString AppendFormat(string format, params object[] args)
    {
        _messageBuilder.AppendFormat(CultureInfo.InvariantCulture, format, args);
        return this;
    }

    public MessageString AppendLine()
    {
        _messageBuilder.AppendLine();
        return this;
    }

    public MessageString AppendLine(string value)
    {
        _messageBuilder.AppendLine(value);
        return this;
    }

    public MessageString AppendLine(MessageString ms)
    {
        _messageBuilder.AppendLine(ms.ToString());
        return this;
    }

    public MessageString AppendLine<T>(T value) where T : IConvertible
    {
        Append<T>(value);
        AppendLine();
        return this;
    }

    public MessageString Clear()
    {
        _messageBuilder.Clear();
        return this;
    }

    public void Dispose()
    {
        _messageBuilder.Clear();
        _messageBuilder = null;
    }

    public int EnsureCapacity(int capacity)
    {
        return _messageBuilder.EnsureCapacity(capacity);
    }

    public bool Equals(MessageString ms)
    {
        return Equals(ms.ToString());
    }

    public bool Equals(StringBuilder sb)
    {
        return _messageBuilder.Equals(sb);
    }

    public bool Equals(string value)
    {
        return Equals(new StringBuilder(value));
    }

    public MessageString Insert<T>(int index, T value)
    {
        _messageBuilder.Insert(index, value);
        return this;
    }

    public MessageString Remove(int startIndex, int length)
    {
        _messageBuilder.Remove(startIndex, length);
        return this;
    }

    public MessageString Replace(char oldChar, char newChar)
    {
        _messageBuilder.Replace(oldChar, newChar);
        return this;
    }

    public MessageString Replace(string oldValue, string newValue)
    {
        _messageBuilder.Replace(oldValue, newValue);
        return this;
    }

    public MessageString Replace(char oldChar, char newChar, int startIndex, int count)
    {
        _messageBuilder.Replace(oldChar, newChar, startIndex, count);
        return this;
    }

    public MessageString Replace(string oldValue, string newValue, int startIndex, int count)
    {
        _messageBuilder.Replace(oldValue, newValue, startIndex, count);
        return this;
    }

    public override string ToString()
    {
        return _messageBuilder.ToString();
    }

    public string ToString(int startIndex, int length)
    {
        return _messageBuilder.ToString(startIndex, length);
    }

    #endregion Public Methods
}
于 2017-06-14T03:30:25.313 回答
0

我通常通过打开一个连接来做到这一点,但在某些情况下,一个简单的测试通过Open导致AccessViolationException

using (SqlConnection db = new SqlConnection(conn))
{    
  db.Open(); // -- Access Violation caused by invalid Server in Connection String
}

因此,我按照 Joel Coehoorn 的建议在开盘前进行了 TCP 检查。用于此的 C# 代码可能是:

string targetAddress = "";
try
{
  targetAddress = GetServerFromConnectionString();
  IPAddress ipAddress = Dns.GetHostEntry(targetAddress).AddressList[0];
  IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 1433);

  using (TcpClient tcpClient = new TcpClient())
  {
       tcpClient.Connect(ipEndPoint);           
  }
            
}
catch (Exception ex)
{
    LogError($"TestViaTcp to server {targetAddress} failed '{ex.GetType().Name}': {ex.Message}");
}
于 2021-09-30T12:35:53.183 回答
0

类似于安德鲁提供的答案,但我使用:

选择 GetDate() 作为 CurrentDate

这使我可以在同一操作中查看 SQL Server 和客户端是否有任何时区差异问题。

于 2017-10-11T14:37:43.877 回答
0

这是我基于@peterincumbria 答案的版本:

using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
return await dbContext.Database.CanConnectAsync(cToken);

我使用 Observable 按间隔轮询健康检查并处理函数的返回值。 try-catch这里不需要,因为: 在此处输入图像描述

于 2021-02-05T09:01:52.820 回答