如何从SQL Server 2008错误码中识别主键重复
本文关键字:识别 误码 错误 SQL Server 2008 | 更新日期: 2023-09-27 18:02:09
我想知道如何从c#中的SQL Server错误代码中识别主键复制错误。
作为一个例子,我有一个c#表单输入数据到SQL Server数据库,当数据输入时发生错误,我如何从异常中识别错误的原因?
如果你捕获SqlException然后看到它的数字,数字2627
将意味着违反唯一约束(包括主键)。
try
{
// insertion code
}
catch (SqlException ex)
{
if (ex.Number == 2627)
{
//Violation of primary key. Handle Exception
}
else throw;
}
MSSQL_ENG002627
这是一个通用错误,无论a是否数据库被复制。在复制数据库中,错误为通常会引发,因为主键没有在整个拓扑中得到适当的管理。
这是一个旧线程,但我想值得注意的是,自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
,这样原始堆栈就不会丢失。
在Entity Framework的情况下,接受的答案将不起作用,错误最终将不会被捕获。这里是一个测试代码,只有实体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;
}
过滤器只复制主键违反异常的工作代码
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