获取SqlConnection失败的原因

时间:2015-08-23 10:55:57

标签: c# enterprise-library sqlconnection

我有一个方法可以返回是否可以打开连接。

但是,如果发生故障,我需要通知用户他们是否提供了错误的登录凭据,或者数据库是否存在问题。

当前代码:

try 
{
    Database db = new SqlDatabase(connectionString);
    using(var connection = db.CreateConnection())
    {
        connection.Open();
        return true;
    }
}
catch (Exception ex)
{
    return false;
}

无论是凭据还是数据库的问题,异常始终是SqlException

但是,我注意到以下差异:

凭据错误

  • 消息:Login failed for user 'whatever'
  • 分类:14
  • 号码:18456
  • 州:1

数据库错误

  • 消息:A network something or other
  • 分类:20
  • 号码:-1
  • 州:0

...是的,有差异,但我不确定我可以依赖这些数字(检查信息的字符串值让我觉得我需要洗澡)。

根据MSDN,Number属性可以是Win32错误代码或服务器错误代码,Class表示严重性,State可以给出不同错误代码的不同含义。

有更好的方法来确定连接失败吗?

2 个答案:

答案 0 :(得分:4)

Sql Server错误代码为documented,您绝对可以依赖它们!

答案 1 :(得分:3)

由于Class属性映射到SQL Server报告的错误的Severity,您可以使用它来确定需要执行的操作。

从SQL Server严重性表中我们了解到:

  • 11-16表示可由用户更正的错误。
  • 14表示与安全相关的错误,例如拒绝权限。
  • 20表示系统问题并且是致命错误......

您的方法可以返回状态代码,具体取决于用户是否可以修复严重性。哪个类别的代码符合您的特定要求,但您可以想象这样的代码:

    public enum Status
    {
        Success = 0,
        None,
        RetryUser,
        RetryInfra,
        Network,
        Boom,
        MAX
    }

    public Status ConnectionStatus()
    {
        Status status = Status.None;

        try
        {
            Database db = new SqlDatabase(connectionString);

            using (var connection = db.CreateConnection())
            {
                connection.Open();
                status = Status.Success;
            }
        }
        catch (SqlException ex)
        {
            switch (ex.Class)
            {
                case 11:
                case 12:
                case 13:
                case 14:
                    status = Status.RetryUser;
                    break;

                case 20:
                    status = Status.RetryInfra;
                    break;

                default:
                    status = Status.Boom;
                    break;
            }
        }

        return status;
    }

从MSDN的Understanding Database Engine Errors我们了解到State可能不是确定下一步的正确选择:

  

可以在数据库引擎的代码中的多个点处引发一些错误消息。例如,可以针对几种不同的条件引发1105错误。引发错误的每个特定条件都会分配一个唯一的状态代码。