获取SqlConnection失败原因

本文关键字:失败 SqlConnection 获取 | 更新日期: 2023-09-27 18:09:14

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

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

当前代码:

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

无论是凭据问题还是数据库问题,例外总是SqlException

但是,我注意到以下区别:

<<p> 坏凭证/strong>:
  • 消息:Login failed for user 'whatever'
  • 类别:14
  • 编号:18456
  • 状态:1

数据库坏:

  • 消息:A network something or other
  • 类别:20
  • 编号:-1
  • 状态:0

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

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

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

获取SqlConnection失败原因

Sql Server错误代码是文档,你可以绝对依赖他们!

由于Class属性映射到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;
    }

从MSDN的理解数据库引擎错误中我们了解到State可能不是确定正确下一步的一个很好的候选者:

在数据库引擎代码的多个点上可能会引发一些错误消息。例如,在几种不同的情况下可能会引发1105错误。每个引发错误的特定条件分配一个唯一的状态码。