【问题标题】:ExecuteReader query with inside of it two ExecuteNonQueryExecuteReader 查询,其中有两个 ExecuteNonQuery
【发布时间】:2019-03-29 07:19:07
【问题描述】:

我遇到了一些从 c# 到 sql 的查询的问题。我需要有一个查询 executeReare 并在其中有一个 if else 允许我在两个插入查询之间进行选择。我正在调用一个小的外部程序(将 url 收集到数据库中),如果选择了 1(通过),则允许我在 1 和 2 之间进行选择(通过),否则(失败)。我不能这样做,因为调试给了我“命令尚未与打开的 DataReader 相关联,需要关闭。” 我不知道该尝试什么了。

private void btnSTART_Click(object sender, RoutedEventArgs e)
{
  sqliteCon.Open();
  if (sqliteCon.State == System.Data.ConnectionState.Open)
  {
    string path = null;//estrazione1
    SqlCommand cmd = new SqlCommand("select nomeI  FROM tabL where selection=1", sqliteCon);
    SqlDataReader nomeIRdr = null;//estrazione2

                    //qui                  
    var scriptsToRun = new List<string>();

    using (nomeIRdr = cmd.ExecuteReader())
    {
      while (nomeIRdr.Read())//estrazione4
      {
        path = nomeIRdr["nomeI"].ToString();//estrazione5

        Process MyProc = Process.Start(path);//permette la run del path contenuto nel db
        MyProc.WaitForExit();
        var exitCode = MyProc.ExitCode;

        if (exitCode == 1)
        {
          scriptsToRun.Add("insert into tabL resItem values 'PASS'");
        }
        else
        {
          scriptsToRun.Add("insert into tabL resItem values 'FAIL'");
        }
        sqliteCon.Close();
      }

    }

    foreach (var script in scriptsToRun)
    {
      SqlCommand cmd1 = new SqlCommand(script, sqliteCon);
      cmd1.ExecuteNonQuery();
    }

  }

}

【问题讨论】:

  • using 块中的声明 2nd 之后,您有两个 nomeItemRdr = cmd.ExecuteReader(); first 初始化。
  • 哦是的小问题我要测试它,但我不认为这是问题
  • '尝试在阅读器关闭的情况下调用读取无效'仍然无法正常工作:(
  • 是的,它是我的,但没有人会给我这个问题的答案,你知道新问题新答案新的可能性,我可以隐藏那个老问题吗?

标签: c# sql wpf


【解决方案1】:

不要共享 single 连接并将所有内容都塞进 single 例程中。请保持您的代码简单

  1. 在查询 RDBMS 时创建(和处理)连接
  2. 提取方法

代码:

流程执行和返回执行结果集合:

// Item1 - path
// Item2 - true in succeed 
private List<Tuple<string, bool>> ExecuteResults() {
  List<Tuple<string, bool>> result = new List<Tuple<string, bool>>();

  using (var con = new SqlConnection(ConnectionStringHere)) {
    con.Open();

    string sql = 
      @"select nomeItem 
          from tabList 
         where selection = 1";

    using (SqlCommand cmd = new SqlCommand(sql, con)) {
      using (var reader = cmd.ExecuteReader()) {
        while (reader.Read()) {
          string path = Convert.ToString(reader[0]);

          using (Process process = Process.Start(path)) {
            process.WaitForExit();

            result.Add(Tuple.Create(path, process.ExitCode == 1)); 
          }
        }
      } 
    }
  }

  return result;
}

在 RDBMS 中保存 results

private void ApplyExecuteResults(IEnumerable<Tuple<string, bool>> results) {
  using (var con = new SqlConnection(ConnectionStringHere)) {
    con.Open();

    string sql = 
      @"update tabList 
           set resItem = @prm_resItem
         where nomeItem = @prm_nomeItem";

    using (SqlCommand cmd = new SqlCommand(sql, con)) {
      cmd.Parameters.Add("@prm_nomeItem", SqlDbType.VarChar);
      cmd.Parameters.Add("@prm_resItem", SqlDbType.VarChar);

      foreach (var item in results) {
        cmd.Parameters[0].Value = item.Item1; 
        cmd.Parameters[1].Value = item.Item2 ? "PASS" : "FAIL"; 

        cmd.ExecuteNonQuery();
      }
    } 
  }
}

最后,结合两个例程:

private void btnSTART_Click(object sender, RoutedEventArgs e) {
  ApplyExecuteResults(ExecuteResults());
}

【讨论】:

  • 在此期间,不要将AddWithValue 与魔术字符串一起使用,而是通过指定其类型来添加参数。
  • @Sami Kuhmonen:是的,最好的选择是 .Add("@prm_resItem", DbType.VarChar);,但我不知道底层 RDBMS 数据类型是什么(是 VarChar?)。这就是为什么我添加了ToDo
  • @mad codroipo:连接通常是pooled(这就是为什么打开和处理它们很便宜)。但是,不要对连接字符串进行硬编码,而是读取它(例如,从设置中)
  • 我已经截取了代码问你是否是正确的实现
  • @mad codroipo: 让我们摆脱 ugly AddWithValue 然后
猜你喜欢
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
相关资源
最近更新 更多