关于c#:以编程方式测试SQL Server连接的最佳方法是什么?

What's the best way to test SQL Server connection programmatically?

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

我可以尝试在每台服务器上获取一个简单的查询,但这意味着我必须在每台服务器上创建一个表、视图或存储过程,即使我使用任何已经创建的SP,我也需要在每台服务器上拥有一个注册用户。服务器不在同一物理位置,因此具有这些需求将是一项复杂的任务。有没有一种简单地从一个SQL服务器"ping"的方法?

事先谢谢!


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


当服务器连接停止或暂停时,我对ef有困难,我提出了同样的问题。因此,为了完整地回答上述问题,这里是代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <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;
        }
    }
}


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
}

建立到数据库的连接不会为您做到这一点吗?如果数据库没有启动,您将无法建立连接。


对于乔尔·科霍恩的建议,您已经尝试过名为tcping的实用程序了吗?我知道这是你没有用程序来做的事情。它是一个独立的可执行文件,允许您对每个指定的时间间隔执行ping操作。但它不在C中。另外..如果目标机器有防火墙,我不确定这是否有效..嗯..

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


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


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

选择getDate()作为当前日期

这允许我在同一个操作中查看SQL Server和客户机是否存在时区差异问题。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
public static class SqlConnectionExtension
{
    #region Public Methods

    public static bool ExIsOpen(this SqlConnection connection, MessageString errorMsg)
    {
        if (connection == null) return false;
        if (connection.State != ConnectionState.Open)
        {
            try
            {
                connection.Open();
            }
            catch (Exception ex) { errorMsg.Append(ex.ToString()); }
        }
        return true;
    }

    public static bool ExIsReady(this SqlConnection connction, MessageString errorMsg)
    {
        if (ExIsOpen(connction, errorMsg) == false) return false;
        try
        {
            using (SqlCommand command = new SqlCommand("select 1", connction))
            using (SqlDataReader reader = command.ExecuteReader())
                if (reader.Read()) return true;
        }
        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
}

为什么不直接连接到SQL Server端口上的telnet会话呢?如果它连接起来,SQL Server就会运行并且很高兴,如果没有,那你就走运了。

另一个stackoverflow帖子可能是一个很好的开始。

编辑:好吧,现在我已经完全阅读了其他文章,这不是最好的解决方案…不过,如果您只想ping端口…


通过C连接到MSSQL是非常有问题的。

一旦我们连接,句柄将不一致,尽管我们在连接后关闭了连接。

我确实在某个地方读到了.NET 4.0版,如果你使用.NET 3.5版,应该没问题。