【问题标题】:Check for exceptions before returing the string value from the query在从查询返回字符串值之前检查异常
【发布时间】:2012-06-13 19:21:15
【问题描述】:

我的函数导致很多异常,因此性能不是那么好。

您能否建议在我返回字符串之前如何修复函数并验证数据?我尝试查看表的数量是否超过 0,但并非总是如此。

    public String getString(String sql)
    {
        DataSet ds = new DataSet();
        string connstring = String.Format("Server={0};Port={1}; User Id={2};Password={3};Database={4};", tbHost, tbPort, tbUser, tbPass, tbDataBaseName);
        NpgsqlConnection conn = new NpgsqlConnection(connstring);
        try
        {
            conn.Open();
            NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
            ds.Reset();
            da.Fill(ds);           
            conn.Close();
            return ds.Tables.Count == 0 ? "0" : ds.Tables[0].Rows[0][0].ToString();
        }
        catch (Exception msg)
        {
            if (conn.State.ToString() == "Open")
            {
                conn.Close();
            }
            return "0";
        }
    }

【问题讨论】:

  • 抛出了什么异常?如果遇到异常,调用方法应该怎么做?
  • 不要在 try 块之外分配变量值并将 .Close() 移动到 finally 块

标签: c# sql winforms postgresql npgsql


【解决方案1】:

您应该使用using 自动处理您创建的对象。您可能会显式打开/关闭连接,但这里不需要这样做,因为行为将完全相同。 DataAdapter 未打开时会打开连接,之后记得关闭它。

关于validate the data - 参见代码中的 cmets。

public String getString(String sql)
{
    using (DataSet ds = new DataSet())
    {
        string connstring = String.Format("Server={0};Port={1}; User Id={2};Password={3};Database={4};", tbHost, tbPort, tbUser, tbPass, tbDataBaseName);
        using (NpgsqlConnection conn = new NpgsqlConnection(connstring))
        {
            using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn))
            {
                da.Fill(ds);
                // You did check count of tables
                if (ds.Tables.Count > 0)
                {
                   DataTable dt = ds.Tables[0];
                   // But forgot to check count of Rows
                   if (dt.Rows.Count > 0)
                   {
                      object o = dt.Rows[0][0];
                      //  And returned value for nulls
                      //  Check for null is here because I don't know
                      //  This Postgresql classes
                      if (o != DBNull.Value && o != null)
                      {
                         return o.ToString();
                      }
                  }
              }
           }
        }
    }
    // Return default value
    return "0";
}

最后一件事 - 在测试枚举时,不要将其转换为字符串。要查看连接是否打开,只需说:

if (conn.State == ConnectionState.Open)

【讨论】:

    【解决方案2】:

    也可以尝试使用“finally”块。

    另外,我建议将 Connect 功能划分为其他方法,以便更好地控制异常发生的位置。

    还可以将存储过程与 SQL 一起使用,以最大限度地减少 SQL 字符串的错误。

    【讨论】:

      【解决方案3】:
      public String getString(String sql)
      {
          DataSet ds = new DataSet();
          string connstring = String.Format("Server={0};Port={1}; User Id={2};Password={3};Database={4};", tbHost, tbPort, tbUser, tbPass, tbDataBaseName);
          NpgsqlConnection conn = new NpgsqlConnection(connstring);
          conn.Open();
          NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
          ds.Reset();
          try
          {
             da.Fill(ds);          
          }
          catch (Exception msg)
          {
              // do something here or log the error.
          }
          finally
          {
             if (conn.State.ToString() == "Open")
             {
                  conn.Close();
             }
          }
          return ds.Tables.Count == 0 ? "0" : ds.Tables[0].Rows[0][0].ToString();
      }
      

      【讨论】:

      • 为了正确起见,我会在那个空的 catch 块中做点什么!
      • 确认!!!你永远不应该有一个空的捕获!也许你的意思是把//Log error
      • 伙计们,我认为在 catch 块中做一些事情是显而易见的。我已经更新了答案
      猜你喜欢
      • 2013-10-24
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      相关资源
      最近更新 更多