我需要開發一個單獨的例程,每5分鐘觸發一次,以檢查SQL Server(10到12)列表是否已啓動並正在運行。以編程方式測試SQL Server連接的最佳方式是什麼?
我可以嘗試在每臺服務器上獲得一個簡單查詢,但這意味着我必須在每臺服務器上創建一個表,視圖或存儲過程,即使我使用任何已經制作好的SP,我也需要一個註冊用戶也在每臺服務器上。服務器不在同一個物理位置,因此具有這些要求將是一項複雜的任務。有沒有辦法簡單地從C#一個SQL Server「ping」?
在此先感謝!
我需要開發一個單獨的例程,每5分鐘觸發一次,以檢查SQL Server(10到12)列表是否已啓動並正在運行。以編程方式測試SQL Server連接的最佳方式是什麼?
我可以嘗試在每臺服務器上獲得一個簡單查詢,但這意味着我必須在每臺服務器上創建一個表,視圖或存儲過程,即使我使用任何已經制作好的SP,我也需要一個註冊用戶也在每臺服務器上。服務器不在同一個物理位置,因此具有這些要求將是一項複雜的任務。有沒有辦法簡單地從C#一個SQL Server「ping」?
在此先感謝!
執行SELECT 1
和檢查的ExecuteScalar返回1
這非常好,不需要在數據庫中創建任何對象,但我需要有一個數據庫和一個用戶來進行查詢。我只想知道該服務是否在MSSQL端口中。無論如何,你正在解決近75%的問題。這將是一個選項。 – backslash17 2010-03-13 21:32:41
無論如何,你有master db :)檢查SQL Server是否運行的最簡單的方法是連接到它。無論如何,連接你需要db和登錄。所有其他解決方案(如ping SQL Server端口)不能保證SQL Server運行正常,任何人都可以連接到它。 – 2010-03-13 21:55:47
不會建立到數據庫的連接爲你做這個嗎?如果數據庫未啓動,您將無法建立連接。
的確如此,簡單地使用ADO net來連接 - 如果在超時期限內沒有響應,那麼數據庫不可用。您不需要發出查詢來確定。 – 2010-03-13 21:21:03
要檢查ADO.NET,我需要一個用戶,我只想檢查服務是否已啓動並正在運行,如果數據庫已啓動,則沒有問題。我需要像telnet這樣的SMTP服務器。沒有必要讓用戶獲得迴應。 – backslash17 2010-03-13 21:26:13
@ backslash17:「用戶登錄失敗...」響應應足以確認1)機器已啓動並且2)服務正在運行。如果您的連接超時,則該服務未運行/正在運行。 – Rory 2010-03-13 21:34:36
查找端口1433打開的監聽器(默認端口)。如果在創建tcp連接後得到任何響應,服務器可能會啓動。
這不會給100%的答案。 – 2010-03-13 21:53:54
@Joel Coehorn:對我來說是一個很好的答案!這方面的例子? – backslash17 2010-03-13 21:58:37
對於Joel Coehorn的建議,你有沒有試過tcping [http://www.elifulkerson.com/projects/tcping.php]。它是一個獨立的可執行文件,它允許您ping每個指定的時間間隔。但它不在C#中。 也..我不知道如果這將工作如果目標機器有防火牆..hmmm .. – 2010-03-14 09:01:55
對於Joel Coehorn的建議,您是否已經試用了名爲tcping的實用程序。我知道這是你沒有編程的東西。它是一個獨立的可執行文件,它允許您ping每個指定的時間間隔。但它不在C#中。另外..我不知道如果這將工作如果目標機器有防火牆..嗯..
[我有點新來這個網站,並錯誤地添加這個作爲評論,現在增加了這個答案。讓我知道如果這可以在這裏完成,因爲我在這裏有重複的評論(作爲評論和答案)。我不能在這裏刪除評論。]
爲什麼不直接連接到sql服務器端口上的telnet會話。如果連接起來,sql server會很快樂,如果沒有的話,你的運氣不好。
這個其他的StackOverflow post可能是一個很好的開始。
編輯: 好了,現在我已經完全閱讀其他職位,這是不完全的最佳解決方案......不過,如果你只是要ping的端口....
我有當連接服務器停止或暫停時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;
}
}
}
沒有必要爲'connection.Close();'在這種情況下,'使用'子句將這樣做你終止後。 – 2013-07-13 00:18:08
絕對100%正確HaLaBi – peterincumbria 2013-07-13 08:55:14
您應該將try catch放在using語句之外。 (http://stackoverflow.com/q/4590490/1248177或http://stackoverflow.com/q/6145245/1248177)。 – aloisdg 2015-01-08 09:45:59
在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);
}
連接通過C#來MSSQL是非常有問題的。
一旦我們連接,手柄將不一致,儘管我們在連接後關閉連接。
我確實讀過.Net 4.0的問題,如果你使用.Net 3.5,它應該沒問題。
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
}
由安德魯提供的答案相似,但我用:
選擇GETDATE()爲的currentdate
這讓我看到,如果SQL Server和客戶端有任何時差問題,採取同樣的行動。
只需ping服務器是不夠的,服務器可能正在運行,但SQL實例將被停止。創建實際的ado.net連接到實例是最好的選擇。 – Rory 2010-03-13 21:26:44
您是否知道您在網站上標記爲「mssql」的_only_問題超出了其他1/2百萬個其他問題?你真的認爲這是一個好標籤嗎?你一直在這裏已經足夠了解更多。 – 2010-03-13 21:44:54
正如您所知,MS-SQL和SQL-server之間存在着很大的差異,特別是如果我們正在討論端口並對它們進行ping操作。什麼是民主,每個人都必須使用相同的標籤。沒有選擇!你應該添加另一個標籤沒有問題,但爲什麼要拿出我選擇的那個! – backslash17 2010-03-13 21:55:00