0

我在 Visual Studio 2010 上有一个 Visual C# 应用程序。在一个表单上,我有 2 个列表框。第一个包含 ID,第二个包含数字,所有这些都保存在我创建的数据库中。我还有一个按钮,我希望在单击该按钮时为第一个 listBox 上出现的每个 ID 更新我的数据库中的一个列,并将所有这些 ID 与另一个表上的其余列一起保存我的数据库。

我在第一部分取得了成功(为出现在列表框中的每个 ID 更新其中一个列),但我无法使第二部分工作。有人告诉我,我必须在两次查询之间等待,但这不会让我的应用程序变慢吗?另外,我不知道该怎么做。

如果我没记错的话,问题是我使用的循环中的循环。

   if (listBox1.Items.Count > 0)
        {
            string kat1 = "Μοριοδοτηθείσα";
            cmd.CommandText = "UPDATE Table2 SET kat_aitisis=@kat WHERE aitisi_ID=@id";

            cmd.Parameters.AddWithValue("@kat", kat1);
            cmd.Parameters.AddWithValue("@id", 0);

            for (int i = 0; i < listBox1.Items.Count; i++)
            {
                cn.Open();
                cmd.Parameters["@id"].Value = Convert.ToInt32(listBox1.Items[i]);
                cmd.ExecuteNonQuery();
                cmd.Clone();

                cmd.CommandText = "select * from Table2 WHERE aitisi_ID=@id";

                        dr = cmd.ExecuteReader();
                        if (dr.HasRows)
                        {
                            while (dr.Read())
                            {

                                 cmd1.CommandText = "Insert INTO Table3 (aitisi_ID,imerominia_aitisis,Epwnimo,Onoma,ADT,Poli,TK,Address,Telephone,email,username,password,IEK,Eidikotita,oikogen_kat,erg_gon,erg_spoy,eisodima_gon,eisodima_spoy,moria) values (dr[0],dr[1],dr[2],dr[3],dr[4],dr[5],dr[6],dr[7],dr[8],dr[9],dr[10],dr[11],dr[12],dr[13],dr[14],dr[15],dr[16],dr[17],dr[18],dr[19])";
                                 cmd1.ExecuteNonQuery();
                                 cmd.Clone();


                            }
                        }
                 cn.Close();
            }


            MessageBox.Show("blahblah.");

        }
4

3 回答 3

2

当 SqlDataReader 打开时,该实例使用的连接不能再用于其他数据访问命令。在您的内部循环中,连接正忙于为 DataReader 提供服务,因此它无法执行该命令。

要解决您的问题,您应该更改连接字符串以添加字符串

"MultipleActiveResultSets=True;"

请参阅 MSDN 上的多个活动结果集

连接字符串,以获取有关如何启用 MARS 连接的示例

编辑

if (listBox1.Items.Count > 0)
{
    SqlCommand cmd = new SqlCommand("UPDATE Table2 SET kat_aitisis=@kat WHERE aitisi_ID=@id";, cn);
    string kat1 = "Μοριοδοτηθείσα";
    cmd.Parameters.AddWithValue("@kat", kat1);
    cmd.Parameters.AddWithValue("@id", 0);

    SqlCommand cmd1 = new SqlCommand("select * from Table2 WHERE aitisi_ID=@id", cn);
    cmd1.Parameters.AddWithValue("@id", 0);

    SqlCommand cmd2 = new SqlCommand("INSERT INTO .......",cn);
    cmd2.Parameters.AddWithValue(.....);
    ... add the remainung cmd2.Parameters...... 

    for (int i = 0; i < listBox1.Items.Count; i++)
    {
         cn.Open();
         cmd.Parameters["@id"].Value = Convert.ToInt32(listBox1.Items[i]);
         cmd.ExecuteNonQuery();

         dr = cmd1.ExecuteReader();
         cmd1.Parameters["@id"].Value = Convert.ToInt32(listBox1.Items[i]);
         while (dr.Read())
         {
             ..set the cmd2 parameters values ...
             cmd2.ExecuteNonQuery();
         }
         MessageBox.Show("blahblah.");
    }
于 2013-05-30T16:39:46.390 回答
0

这段代码写得很糟糕,会对性能造成很大影响。因为您正在循环连接到数据库并进行多次迭代的 DML 操作。在这里我建议

  1. 创建一个存储过程
  2. 将来自前端的所有信息收集到 XML 中并将该 XML 传递给 SP。
  3. 在此 SP 中将数据解析为临时变量/表
  4. 在连接的基础上使用批量更新和插入
于 2013-05-30T16:42:52.917 回答
-1

您的代码中有一些问题:

第一的:

 cmd1.CommandText = "Insert INTO Table3 (aitisi_ID,imerominia_aitisis,Epwnimo,Onoma,ADT,Poli,TK,Address,Telephone,email,username,password,IEK,Eidikotita,oikogen_kat,erg_gon,erg_spoy,eisodima_gon,eisodima_spoy,moria) values (dr[0],dr[1],dr[2],dr[3],dr[4],dr[5],dr[6],dr[7],dr[8],dr[9],dr[10],dr[11],dr[12],dr[13],dr[14],dr[15],dr[16],dr[17],dr[18],dr[19])";

没有将 datareader 的值插入到命令文本中。

第二:如果我在你的位置,我会在循环中创建命令文本,并连接你的命令文本,然后通过单个请求将其传递给 sql server。它会更快。

                    var commandText = string.Empty;
                    if (dr.HasRows)
                    {
                        while (dr.Read())
                        {

                            commandText += string.Format("Insert INTO Table3 (aitisi_ID,imerominia_aitisis,Epwnimo,Onoma,ADT,Poli,TK,Address,Telephone,email,username,password,IEK,Eidikotita,oikogen_kat,erg_gon,erg_spoy,eisodima_gon,eisodima_spoy,moria) values ({0}, {1},...{19}) Go", dr[0], dr[1],...dr[19]);
                        }
                         cmd1.CommandText = commandText;
                    }
 ...
 cmd1.ExecuteNonQuery();
于 2013-05-30T16:43:24.533 回答