Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 抓到“我”是一种坏习惯吗;“快乐之路”;有例外吗?_C#_Sql_Error Handling_Try Catch - Fatal编程技术网

C# 抓到“我”是一种坏习惯吗;“快乐之路”;有例外吗?

C# 抓到“我”是一种坏习惯吗;“快乐之路”;有例外吗?,c#,sql,error-handling,try-catch,C#,Sql,Error Handling,Try Catch,我有一个SQL语句,它检查一个值是否在我的数据库中。如果值不在数据库中,我想用“快乐路径”来响应。 我发现使用DbDataReader(.NET)时,如果SELECT查询找不到值,它会抛出一个异常-因此我的“快乐路径”最终出现在异常中,而不是主try块中 我总是可以说“notin”,但我不想返回数据库中所有没有该值的行,因为这将返回数千个结果,而我只需要一个“no it is NOT here”类型的响应 public void wristbandScan(string barcode)

我有一个SQL语句,它检查一个值是否在我的数据库中。如果值不在数据库中,我想用“快乐路径”来响应。 我发现使用DbDataReader(.NET)时,如果SELECT查询找不到值,它会抛出一个异常-因此我的“快乐路径”最终出现在异常中,而不是主try块中

我总是可以说“notin”,但我不想返回数据库中所有没有该值的行,因为这将返回数千个结果,而我只需要一个“no it is NOT here”类型的响应

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语句的所有行相关联的延迟


是否有更好的方法来执行此操作,或者此方法是可接受的最佳做法?

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

然后处理
try/catch

之外的无行场景。好吧,您不必将所有记录提取到客户端;让我们为此提取一个方法。假设您使用的是
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
;它们是危险的-在您当前的代码中,您捕获了太多的异常:例如,
AccessViolationException
,如果它被抛出到
dbRunner中的某个地方。查询此
将被有效屏蔽。

是的,非常糟糕的做法。例外是非常昂贵的,应该是:例外,不是你期望发生的事情,更不用说“快乐”的结果了!我就是这么想的。那么,如何让SELECT语句在找不到值时不返回异常呢?也许限制是我对SQL的了解?通常,如果一个SELECT查询找不到值,它会抛出一个异常?在什么情况下是真的??通常,查询返回一个空结果集。什么是
\u dbRunner.queryThis
?最好从一个类似ORM(对象到关系管理器)的实体框架开始(还有其他选项可用),此时您可以将表视为对象的集合,而不必担心底层的SQL代码。它还可以消除当前代码可能遭受的SQL注入攻击。我不知道为什么
SELECT
会抛出异常如果找不到结果,它应该返回一个空集。但是,如果您只关心条形码的存在,您可以将查询从链接的票证更改为
COUNT(1)\u barcode=
。如果找不到匹配项,这将返回0,否则将返回大于0的值谢谢这个解决方案,我重新设计了我的实现,效果很好。