2010-03-13 71 views
50

我需要開發一個單獨的例程,每5分鐘觸發一次,以檢查SQL Server(10到12)列表是否已啓動並正在運行。以編程方式測試SQL Server連接的最佳方式是什麼?

我可以嘗試在每臺服務器上獲得一個簡單查詢,但這意味着我必須在每臺服務器上創建一個表,視圖或存儲過程,即使我使用任何已經制作好的SP,我也需要一個註冊用戶也在每臺服務器上。服務器不在同一個物理位置,因此具有這些要求將是一項複雜的任務。有沒有辦法簡單地從C#一個SQL Server「ping」?

在此先感謝!

+2

只需ping服務器是不夠的,服務器可能正在運行,但SQL實例將被停止。創建實際的ado.net連接到實例是最好的選擇。 – Rory 2010-03-13 21:26:44

+0

您是否知道您在網站上標記爲「mssql」的_only_問題超出了其他1/2百萬個其他問題?你真的認爲這是一個好標籤嗎?你一直在這裏已經足夠了解更多。 – 2010-03-13 21:44:54

+1

正如您所知,MS-SQL和SQL-server之間存在着很大的差異,特別是如果我們正在討論端口並對它們進行ping操作。什麼是民主,每個人都必須使用相同的標籤。沒有選擇!你應該添加另一個標籤沒有問題,但爲什麼要拿出我選擇的那個! – backslash17 2010-03-13 21:55:00

回答

52

執行SELECT 1和檢查的ExecuteScalar返回1

+0

這非常好,不需要在數據庫中創建任何對象,但我需要有一個數據庫和一個用戶來進行查詢。我只想知道該服務是否在MSSQL端口中。無論如何,你正在解決近75%的問題。這將是一個選項。 – backslash17 2010-03-13 21:32:41

+2

無論如何,你有master db :)檢查SQL Server是否運行的最簡單的方法是連接到它。無論如何,連接你需要db和登錄。所有其他解決方案(如ping SQL Server端口)不能保證SQL Server運行正常,任何人都可以連接到它。 – 2010-03-13 21:55:47

7

不會建立到數據庫的連接爲你做這個嗎?如果數據庫未啓動,您將無法建立連接。

+0

的確如此,簡單地使用ADO net來連接 - 如果在超時期限內沒有響應,那麼數據庫不可用。您不需要發出查詢來確定。 – 2010-03-13 21:21:03

+0

要檢查ADO.NET,我需要一個用戶,我只想檢查服務是否已啓動並正在運行,如果數據庫已啓動,則沒有問題。我需要像telnet這樣的SMTP服務器。沒有必要讓用戶獲得迴應。 – backslash17 2010-03-13 21:26:13

+3

@ backslash17:「用戶登錄失敗...」響應應足以確認1)機器已啓動並且2)服務正在運行。如果您的連接超時,則該服務未運行/正在運行。 – Rory 2010-03-13 21:34:36

1

查找端口1433打開的監聽器(默認端口)。如果在創建tcp連接後得到任何響應,服務器可能會啓動。

+1

這不會給100%的答案。 – 2010-03-13 21:53:54

+0

@Joel Coehorn:對我來說是一個很好的答案!這方面的例子? – backslash17 2010-03-13 21:58:37

+0

對於Joel Coehorn的建議,你有沒有試過tcping [http://www.elifulkerson.com/projects/tcping.php]。它是一個獨立的可執行文件,它允許您ping每個指定的時間間隔。但它不在C#中。 也..我不知道如果這將工作如果目標機器有防火牆..hmmm .. – 2010-03-14 09:01:55

1

對於Joel Coehorn的建議,您是否已經試用了名爲tcping的實用程序。我知道這是你沒有編程的東西。它是一個獨立的可執行文件,它允許您ping每個指定的時間間隔。但它不在C#中。另外..我不知道如果這將工作如果目標機器有防火牆..嗯..

[我有點新來這個網站,並錯誤地添加這個作爲評論,現在增加了這個答案。讓我知道如果這可以在這裏完成,因爲我在這裏有重複的評論(作爲評論和答案)。我不能在這裏刪除評論。]

0

爲什麼不直接連接到sql服務器端口上的telnet會話。如果連接起來,sql server會很快樂,如果沒有的話,你的運氣不好。

這個其他的StackOverflow post可能是一個很好的開始。

編輯: 好了,現在我已經完全閱讀其他職位,這是不完全的最佳解決方案......不過,如果你只是要ping的端口....

42

我有當連接服務器停止或暫停時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; 
     } 
    } 
} 
+9

沒有必要爲'connection.Close();'在這種情況下,'使用'子句將這樣做你終止後。 – 2013-07-13 00:18:08

+0

絕對100%正確HaLaBi – peterincumbria 2013-07-13 08:55:14

+3

您應該將try catch放在using語句之外。 (http://stackoverflow.com/q/4590490/1248177或http://stackoverflow.com/q/6145245/1248177)。 – aloisdg 2015-01-08 09:45:59

10

在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); 
} 
-3

連接通過C#來MSSQL是非常有問題的。

一旦我們連接,手柄將不一致,儘管我們在連接後關閉連接。

我確實讀過.Net 4.0的問題,如果你使用.Net 3.5,它應該沒問題。

0
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 
} 
0

由安德魯提供的答案相似,但我用:

選擇GETDATE()爲的currentdate

這讓我看到,如果SQL Server和客戶端有任何時差問題,採取同樣的行動。

相關問題