如何从SQL Server 2008错误代码中识别主键重复?

Ros*_*han 18 c# sql-server entity-framework

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

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

Hab*_*bib 51

如果捕获SqlException然后查看其编号,则该编号2627将表示违反唯一约束(包括主键).

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

MSSQL_ENG002627

无论是否复制数据库,这都是可以引发的一般错误.在复制数据库中,通常会引发错误, 因为未在拓扑中正确管理主键.

  • 我相信2601也可能是唯一的索引违规 (4认同)
  • @Roshan你必须使用`SqlException`,而不是`System.Exception`,如果你同时使用它们,请确保更具体的异常将其catch块置于不太具体的异常之上(在这种情况下,`sqlException`的catch块必须在"异常"的捕获块之上. (3认同)
  • 还值得注意的是,您可以使用异常过滤,因此您最终会得到:`try{ //insertion code } catch(SqlException ex) when (ex.Number == 2627){ //do something }` (2认同)

Bru*_*cia 5

这是一个旧线程,但是我想值得注意的是,由于使用C#6,您可以:

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

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

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

与公认的答案相比,此方法的最大优点是:

如果错误号等于2627,因此不是唯一的键冲突,则不会捕获异常。

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