SQL Server 연결을 프로그래밍 방식으로 테스트하는 가장 좋은 방법은 무엇입니까?


78

SQL Server 목록 (10-12)이 실행 중인지 확인하기 위해 5 분마다 실행되는 단일 루틴을 개발해야합니다.

각 서버에서 간단한 쿼리를 얻을 수 있지만 이는 이미 만들어진 SP를 사용하더라도 모든 서버에서 테이블, 뷰 또는 저장 프로 시저를 만들어야 함을 의미합니다. 각 서버에 등록 된 사용자가 있어야합니다. 서버도. 서버가 동일한 물리적 위치에 있지 않으므로 이러한 요구 사항을 충족하는 것은 복잡한 작업입니다. C # one SQL Server에서 단순히 "ping"하는 방법이 있습니까?

미리 감사드립니다!


2
단순히 서버를 핑하는 것만으로는 충분하지 않습니다. 서버는 실행 중이지만 SQL 인스턴스는 중지 될 수 있습니다. 인스턴스에 대한 실제 ado.net 연결을 만드는 것이 가장 좋은 방법입니다.
Rory

사이트에 있는 유일한 질문이 mssql50 만 개가 넘는 다른 질문에 태그 되어 있다는 것을 알고 계셨습니까 ? 정말 좋은 태그라고 생각하세요? 당신은 더 잘 알기에 충분히 오랫동안 여기에 계셨습니다.
Joel Coehoorn

2
아시다시피 MS-SQL과 SQL-server 사이에는 큰 차이가 있습니다. 특히 포트에 대해 이야기하고 핑하는 경우에 그렇습니다. 얼마나 민주주의인가, 모두가 같은 태그를 사용해야합니다. 옵션이 없습니다! 문제없이 다른 태그를 추가해야하지만 내가 선택한 태그를 제거해야하는 이유 !!!!
backslash17

2
MS-SQL IS SQL 서버 - 제품의 이름 입니다 SQL 서버.
marc_s

8
SQL Server는 다음을 참조 할 수 있습니다.-Structured Query Language를 구현하는 모든 데이터베이스 서버-Microsoft SQL Server, Microsoft의 특정 구현 데이터베이스 서버-Sybase에서 개발 한 관계형 데이터베이스 서버 인 Sybase SQL Server. ------- 보시다시피 SQL 서버에는 두 가지 이상의 의미가 있으며 이것이 제가 MSSQL 태그를 사용한 이유입니다
backslash17

답변:


75

실행 SELECT 1하고 ExecuteScalar가 1을 반환하는지 확인합니다.


1
매우 훌륭하고 데이터베이스에 개체를 만들 필요가 없지만 쿼리를 만들려면 데이터베이스와 사용자가 필요합니다. 서비스가 MSSQL 포트에 있는지 알고 싶습니다. 어쨌든 문제의 거의 75 %를 해결하고 있습니다. 이것은 옵션이 될 것입니다.
backslash17

5
어쨌든 master db가 있습니다. :) SQL Server가 실행 중인지 확인하는 가장 깨끗한 방법은 연결하는 것입니다. 연결하려면 db와 로그인이 필요합니다. 다른 모든 솔루션 (예 : SQL Server 포트 ping)은 SQL Server가 제대로 실행되고 누구든지 연결할 수 있음을 보장하지 않습니다.
Andrew Bezzub

내 진짜 의도가 찬성하는 동안 실수 로이 답변에 반대 투표했습니다. 나는 이것을 하루 만에 깨달았 기 때문에 더 이상 내 실수를 고칠 수 없습니다.
Giorgos Betsos

1
@GiorgosBetsos - 나는 당신의 실수 - D 고정
쿠날 B.

80

서버 연결이 중지되거나 일시 중지되었을 때 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;
        }
    }
}

14
필요 connection.Close();이 경우는 using절은 종료시 당신을 위해 그것을 할 것.

3
using 문 외부에 try catch를 넣어야합니다. ( stackoverflow.com/q/4590490/1248177 또는 stackoverflow.com/q/6145245/1248177 ).
codidact.com로 이동 aloisdg

1
@aloisdg-그것은 의존하지 않습니다. 데이터베이스에 연결할 수 있는지 테스트하고 예외적 인 상황에서만 연결할 수없는 경우 거짓을 반환합니다. 또는 SQL 연결을 잘못 구성하는 것과 관련하여 예외를 삼키기를 원합니다. 방금 위 코드에 대해 코딩 한 것과 같은 차이점이 있음을 알고 있습니다.
brumScouse

13

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

7

데이터베이스에 대한 연결을 설정하지 않겠습니까? 데이터베이스가 작동하지 않으면 연결을 설정할 수 없습니다.


실제로 ADO net을 사용하여 연결하기 만하면됩니다. 제한 시간 내에 응답이 없으면 데이터베이스를 사용할 수 없습니다. 이를 확인하기 위해 쿼리를 발행 할 필요가 없습니다.
Dan Diplo

ADO.NET으로 확인하려면 사용자가 필요합니다. 서비스가 실행 중인지 확인하고 데이터베이스가 실행 중인지 확인하고 싶습니다. 텔넷과 SMTP 서버가 필요합니다. 사용자가 응답을받을 필요가 없습니다.
backslash17

3
@ backslash17 : "사용자 로그인 실패 ..."응답은 1) 머신이 작동 중이고 2) 서비스가 실행 중인지 확인하기에 충분해야합니다. 연결 시간 초과가 발생하면 서비스가 실행 / 작동하지 않는 것입니다.
Rory

@Rory : 좋은 지적! try / catch 블록에서 오류를 확인하는 문제입니다. 감사!
backslash17

@ backslash17 "Login failed for user"에 별도의 오류 코드 또는이를 확인하는 데 도움이되는 내용이 있는지 확인하십시오. 예외 메시지로 오류를 구분하는 것은 매우 나쁜 습관입니다.
Andrew Bezzub

1

포트 1433 (기본 포트)에서 열린 리스너를 찾으십시오. 거기에서 tcp 연결을 만든 후 응답을 받으면 서버가 작동 중일 수 있습니다.


Joel Coehorn이 제안한 내용에 대해 tcping [ elifulkerson.com/projects/tcping.php] 을 이미 사용해 보셨습니까 ? 지정된 시간 간격마다 ping을 수행 할 수있는 독립 실행 형 실행 파일입니다. 그래도 C #에는 없습니다. 대상 컴퓨터 .. firewall..hmmm 경우 Also..I는 확인이 작동 것 아니에요 경우
인 Ashish 굽타에게

1

Joel Coehorn이 제안한 내용에 대해 tcping이라는 유틸리티를 이미 사용해 보셨습니까 ? 나는 이것이 당신이 프로그래밍 방식으로하지 않는 것임을 알고 있습니다. 지정된 시간 간격마다 ping을 수행 할 수있는 독립 실행 형 실행 파일입니다. 그래도 C #에는 없습니다. 또한 .. 대상 컴퓨터에 방화벽이있는 경우 이것이 작동하는지 모르겠습니다 ..hmmm ..

[저는이 사이트에 익숙하지 않아 실수로 댓글로 추가했습니다. 이제 답변으로 추가했습니다. 여기에 중복 된 댓글 (댓글 및 답변)이 있으므로 여기에서이 작업을 수행 할 수 있는지 알려주세요. 여기에서는 댓글을 삭제할 수 없습니다.]


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
}

0

Andrew가 제공 한 답변과 비슷하지만 다음을 사용합니다.

CurrentDate로 GetDate ()를 선택하십시오.

이를 통해 SQL Server와 클라이언트에 동일한 작업에서 표준 시간대 차이 문제가 있는지 확인할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.