代码之家  ›  专栏  ›  技术社区  ›  Yehuda Shapira

获取SqlConnection失败原因

  •  2
  • Yehuda Shapira  · 技术社区  · 9 年前

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

    但是,如果失败,我需要通知用户他们是否提供了错误的登录凭据,或者数据库是否有问题。

    当前代码:

    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 回复  |  直到 9 年前
        1
  •  4
  •   Vincenzo    9 年前

    Sql Server错误代码为 documented 你绝对可以信赖他们!

        2
  •  4
  •   rene    9 年前

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

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

    从…起 Understanding Database Engine Errors 在MSDN,我们了解到 State 可能不是确定正确下一步的好人选:

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