在例外情况下抓住“幸福之路”是否是错误的做法?

时间:2019-06-18 13:27:18

标签: c# sql error-handling try-catch

我有一条SQL语句,用于检查数据库中是否有值。如果数据库中的值是 not ,我想用“幸福的道路”做出回应。 我发现使用DbDataReader(.NET)时,如果SELECT查询找不到该值,则会引发异常-因此,我的“快乐之路”最终会出现在异常中,而不是在主try块中。

我总是可以说“ NOT IN”,但是我不想返回数据库中所有没有值的行-因为这将返回成千上万的结果,而我想要的只是一个“不,不是这里”类型的响应。

public void wristbandScan(string barcode)
    {
        string query = "SELECT ticket FROM tickets WHERE 
                             linked_barcode='" + barcode + "'";

        ValidTicketEventArgs args = new ValidTicketEventArgs();

        try
        {
            var queryResult = _dbRunner.queryThis(query);

            args.Result = false;
            args.Message = "WB already linked";
            args.Barcode = barcode; 
            OnValidTicketEvent(args);
        }
        catch (Exception e)
        {
            this.updateWristband(barcode);
            this.updateValid();
            args.Result = true;
            args.Message = "WB linked";
            args.Barcode = barcode;
            OnValidTicketEvent(args);
        }
    }

在错误语句中找到快乐的道路对我来说是错误的,但是我不希望与用NOT IN语句读取所有行相关联的滞后。

是否有更好的方法可以做到这一点?或者这种方法可以接受为最佳做法?

2 个答案:

答案 0 :(得分:2)

好吧,您不必提取所有记录到客户端;为此,我们提取一种方法。假设您使用MS Sql

 public bool hasScanCode(string barcode) {
   if (string.IsNullOrWhiteSpace(barcode)) 
     return false;

   //DONE: paramterize queries 
   string query = 
      @"SELECT ticket 
          FROM tickets 
         WHERE linked_barcode = @prm_BarCode";

   using (var conn = new SqlConnection(connection_string_here)) {
     conn.Open();

     using (var q = new SqlCommand(conn, query)) {
       //TODO: q.Parameters.Add is a better choice
       q.Parameters.AddWithValue("@prm_BarCode", barcode.Trim()); 

       using (var reader = q.ExecuteReader()) {
         // we read (fetch) at most 1 record
         // if empty cursor - no record with given barcode 
         return reader.Read(); 
       }
     }
   }
 }

然后我们可以使用它:

 public void wristbandScan(string barcode) {
   bool result = hasScanCode(barcode); 

   ValidTicketEventArgs args = new ValidTicketEventArgs() { 
     Result = result,
     Message = result ? "WB linked" : "WB already linked",
     Barcode = barcode, 
   };  

   OnValidTicketEvent(args);       
 }

请记住-例外用于例外情况。异常非常(堆栈展开需要资源);它们是可读的-catch实际上是臭名昭著的goto;它们是危险-在您当前的代码中,您catch 有太多例外:例如AccessViolationException(如果扔在dbRunner.queryThis内的某个地方,将被有效地屏蔽

答案 1 :(得分:0)

创建并调用一个StoredProcedure,它可以处理空情况,不返回任何行,而不会返回异常。

然后处理try/catch之外的无行方案。