2013-03-05 79 views

回答

47

如果你抓到SqlException然后看到它的号码,数字2627将意味着违反唯一约束(包括主键)。

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

MSSQL_ENG002627

这是可以不管的 数据库是否被复制被提出了一般性错误。在复制数据库中,通常会引发错误 ,因为在整个拓扑中主键没有得到适当的管理

+3

@Roshan如果你同时使用它们,你必须使用'SqlException'而不是'System.Exception',确保更具体的异常有它的catch块在不太特定的异常之上(在这种情况下catch块'SqlException '必须在'Exception'的catch块之上)。 – 2013-03-05 07:20:02

+3

我相信2601也可以是唯一索引违反 – Brain2000 2015-07-14 16:06:45

+1

还值得注意的是,这样你就结束了,你可以使用异常过滤: '尝试{// 插入代码 } 赶上(SQLEXCEPTION前)时(ex.Number = = 2627){ //做某事 }' – MJJames 2016-10-26 10:51:33

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

这是一个古老的线程,但我想这是值得一提的是,由于C#6你可以:

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

并与C#7和包裹除外(例如实体框架核心):

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

与接受的答案比较,这种方法的最大优点是:

如果错误编号为而不是等于2627并且因此它不是唯一的密钥违规,则不会捕获异常。

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