26

我想知道我们如何从 C# 中的 SQL Server 错误代码中识别主键重复错误。

例如,我有一个 C# 表单将数据输入 SQL Server 数据库,当数据输入时发生错误时,如何从异常中识别错误原因?

4

4 回答 4

65

如果您捕获SqlException然后查看它的编号,该编号2627将意味着违反唯一约束(包括主键)。

try
{
    // insertion code
}
catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        //Violation of primary key. Handle Exception
    }
    else throw;
}

MSSQL_ENG002627

这是一个无论是否复制数据库都可能引发的一般错误。在复制的数据库中, 通常会引发错误,因为没有在拓扑中适当地管理主键。

于 2013-03-05T07:06:23.237 回答
8

这是一个旧线程,但我想值得注意的是,从 C#6 开始,您可以:

try
{
    await command.ExecuteNonQueryAsync(cancellation);
}
catch (SqlException ex) when (ex.Number == 2627)
{
    // Handle unique key violation
}

并使用 C#7 和包装异常(如 Entity Framework Core):

try
{
    await _context.SaveChangesAsync(cancellation);
}
catch (DbUpdateException ex) 
   when ((ex.InnerException as SqlException)?.Number == 2627)
{
    // Handle unique key violation
}

与公认的答案相比,这种方法的最大优势是:

如果错误号等于 2627,因此它不是唯一键违规,则不会捕获异常。

如果没有异常过滤器 ( when),您最好记住重新抛出该异常,以防您无法处理它。理想情况下不要忘记使用ExceptionDispatchInfo,以免丢失原始堆栈。

于 2017-09-12T19:03:56.660 回答
0

在实体框架的情况下,接受的答案将不起作用,错误最终不会被捕获。这是一个测试代码,只有实体 catch 语句会被命中,或者如果实体语句被删除,当然会出现通用异常:

try
{
    db.InsertProcedureCall(id);
}
catch (SqlException e0)
{
   // Won't catch
}
catch (EntityCommandExecutionException e1)
{
    // Will catch
    var se = e1.InnerException as SqlException;
    var code = se.Number;
}
catch (Exception e2)
{
   // if the Entity catch is removed, this will work too
    var se = e2.InnerException as SqlException;
    var code = se.Number;
}
于 2017-08-16T21:36:16.030 回答
0

过滤器的工作代码仅重复主键破坏异常

using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
.........

 try{
    abc...
    }
    catch (DbUpdateException ex)
                {
                    if (ex.InnerException.InnerException is SqlException sqlEx && sqlEx.Number == 2601)
                    {
                        return ex.ToString();
                    }
                    else
                    {
                        throw;
                    }
                }

注意细节:- ex.InnerException.InnerException 不是 ex.InnerException

于 2019-04-09T09:31:54.370 回答