SQL Server(10〜12)のリストが稼働しているかどうかを確認するために、5分ごとに起動される単一のルーチンを開発する必要があります。
最小限のコードとSQLの運用要件でC#1からSQL Serverを単純に「ping」する方法はありますか?
SQL Server(10〜12)のリストが稼働しているかどうかを確認するために、5分ごとに起動される単一のルーチンを開発する必要があります。
最小限のコードとSQLの運用要件でC#1からSQL Serverを単純に「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;
}
}
}
実行SELECT 1
して、ExecuteScalarが1を返すかどうかを確認します。
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);
}
データベースへの接続を確立することはあなたのためにこれをしませんか?データベースが起動していない場合、接続を確立することはできません。
ポート1433(デフォルトのポート)で開いているリスナーを探します。そこでtcp接続を作成した後に応答があった場合は、サーバーが稼働している可能性があります。
ご存知のとおり、私は2010年にこれを最初に作成しました。今日は、実際にサーバーに接続しようとしています。
Joel Coehornが提案したことについては、tcpingという名前のユーティリティをすでに試しましたか。これはあなたがプログラムでやっていないことだと私は知っています。これはスタンドアロンの実行可能ファイルであり、指定された時間間隔ごとにpingを実行できます。ただし、C#ではありません。また..これが機能するかどうかはわかりません。ターゲットマシンにファイアウォールがある場合..hmmm..
[私はこのサイトに少し慣れていないので、これを誤ってコメントとして追加しましたが、今はこれを回答として追加しています。ここに(コメントと回答として)重複したコメントがあるので、これがここでできるかどうか教えてください。ここでコメントを削除することはできません。]
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
}
アンドリューによって提供された答えに似ていますが、私は使用します:
CurrentDateとしてGetDate()を選択します
これにより、SQL Serverとクライアントにタイムゾーンの違いの問題があるかどうかを、同じアクションで確認できます。
これが@peterincumbriaの回答に基づく私のバージョンです:
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
return await dbContext.Database.CanConnectAsync(cToken);
Observableを使用して、間隔によるヘルスチェックのポーリングと関数の戻り値の処理を行っています。
try-catch
ここでは必要ありません。理由は次のとおりです。
私は通常、接続を開くことでこれを行いますが、簡単なテスト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}");
}