我有一个存储过程来在SQL Server DB中插入数据。我正在使用WCF服务,它从客户端获取数据并在数据库中插入数据。我的数据库表的Name列有一个唯一的键约束。
如果存在任何唯一键约束错误:
我在存储过程中处理它。例如,在SQL Server中使用if exists语句,如果有值,那么我应该返回-1,否则它应该在db中插入行。
我在我的(WCF服务)c#代码中处理它。我得到sql异常并将该sql异常代码返回给客户端。
在第一个解决方案中,我认为存在性能问题,因为将检查2次唯一键约束。我第一次在存储过程中手动检查它,第二次唯一键约束将再次检查它。因此,正在检查1个值。
在第二个解决方案中,使用c#代码处理wcf服务的异常,我听说wcf中的异常不太好。
什么是最好的解决方案?
答案 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,但总会如此?