在Db或c#代码中更好地处理异常?

时间:2016-03-26 10:31:41

标签: c# sql-server wcf stored-procedures exception-handling

我有一个存储过程来在SQL Server DB中插入数据。我正在使用WCF服务,它从客户端获取数据并在数据库中插入数据。我的数据库表的Name列有一个唯一的键约束。

如果存在任何唯一键约束错误:

  1. 我在存储过程中处理它。例如,在SQL Server中使用if exists语句,如果有值,那么我应该返回-1,否则它应该在db中插入行。

  2. 我在我的(WCF服务)c#代码中处理它。我得到sql异常并将该sql异常代码返回给客户端。

  3. 在第一个解决方案中,我认为存在性能问题,因为将检查2次唯一键约束。我第一次在存储过程中手动检查它,第二次唯一键约束将再次检查它。因此,正在检查1个值。

    在第二个解决方案中,使用c#代码处理wcf服务的异常,我听说wcf中的异常不太好。

    什么是最好的解决方案?

1 个答案:

答案 0 :(得分:2)

"更好的"这里有点主观,它的种类取决于哪个"更好"你喜欢。

  • 如果从性能角度来看,我愿意打赌选项1实际上更具性能,因为检查SQL Server中现有值的索引(甚至两次)的过程将会将异常提升并传播回代码所花费的时间可能会相形见绌。 (更不用说你根本不必检查它两次,你可以尝试/捕获T-SQL本身并在唯一键违反时返回-1)

  • 但是,如果从设计和维护的角度来看,那么选项2在我看来更为可取,因为它非常清楚发生了什么

换句话说,作为开发人员,我宁愿阅读(伪代码)

//assuming you have a connection open, a command prepared, etc.
try
{
    var result=command.ExecuteNonQuery();
}
catch(SqlException ex)
{
    if(ex.Number==2627)
    {
        //Unique Key constraint violation.
        //Error 2627 is documented and well known to be a Unique Key Constraint Violation 
       //so it's immediately obvious what's going on here
    } 
}

大于

var result=command.ExecuteNonQuery();
if (result==-1)
{
   //this means a unique key violation
   //what if that comment got removed? I'd have no clue what
   //-1 meant...
}

即使乍一看,第二个更短,也更娴熟。

注意:正如MetroSmurf指出的那样,在此处捕获异常并不理想,它应该由调用者处理,因此这仅用于说明目的。

  

这是因为这里的-1在存储过程方面非常随意;所以,除非你能保证你可以记录它并且这个文件永远不会过时等,那么你可能会给下一个开发人员带来负担,必须去查找存储过程,然后弄清楚究竟是什么 - 1意味着在这种情况下。

另外,因为有人可以在不触及您的C#的情况下更改SP,如果SP突然开始返回,您打算做什么?#34; 42"对于唯一密钥违规?当然,你可能完全控制SP,但总会如此?