通过ListViews循环检查项目以执行存储过程

时间:2013-06-17 10:54:21

标签: c# winforms stored-procedures

我所拥有的是ListView,其中包含列表中每个项目的复选框。

点击按钮,我会像这样收集我的“已检查项目”;

ListView.CheckedListViewItemCollection checkedItems = emps.CheckedItems;

            List<string> attend = new List<string>();

            foreach (ListViewItem item in checkedItems)
            {
                attend.Add(item.Text);
            }

我知道这是有效的,因为我打印了这样的内容;

string s = String.Join(",", attend); MessageBox.Show(s);

但是,我想采用这些strings并为列表中的每个字符串运行SQL存储过程(attend)。

像这样;

SqlConnection con = new SqlConnection(conn);
            con.Open();
            SqlCommand cmd = new SqlCommand("my_SP", con);
            cmd.CommandType = CommandType.StoredProcedure;

            foreach (string item in attend)
            {
                cmd.Parameters.Clear();
                cmd.Parameters.Add(new SqlParameter("@Name", item));
                cmd.Parameters.Add(new SqlParameter("@Course", attender.SelectedValue));
                cmd.ExecuteReader();
            }
            con.Close();

当我检查列表中的一个项目时,当我检查多个项目失败时,这非常有效。

错误消息是;

There is already an open DataReader associated with this Command which must be closed first.

我已经尝试更改命令的变量名等,但是我看不到DataReader打开的位置,我之前没有遇到过这个错误。

4 个答案:

答案 0 :(得分:1)

打开连接时尝试以下方法

using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
   //...etc
}

答案 1 :(得分:1)

因为你在循环中使用

cmd.ExecuteReader();

这个,在第一个循环打开一个SqlDataReader(它是未分配但它仍然存在)然后,当你重新执行循环时,未使用的SqlDataReader仍然阻止连接。

改为使用

cmd.ExecuteNonQuery();

当您需要从数据库中读取数据时,应该使用Recute ExecuteReader,而不是在需要执行插入,更新,删除操作时,因此应该以这种方式更改代码

    using(SqlConnection con = new SqlConnection(conn))
    using(SqlCommand cmd = new SqlCommand("my_SP", con))
    {
        con.Open();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@Name", ""));
        cmd.Parameters.Add(new SqlParameter("@Course", ""));
        foreach (string item in attend)
        {
            cmd.Parameters["@Name"].Value = item;
            cmd.Parameters["@Course"].Value  = attender.SelectedValue);
            cmd.ExecuteNonQuery();
        }
     }

此参数也可以在循环外声明并添加,仅更改循环内的值。这样可以提高速度

答案 2 :(得分:0)

尝试使用以下代码

SqlConnection con = new SqlConnection(conn);
            con.Open();


            foreach (string item in attend)
            {
                cmd.Parameters.Clear();
                cmd.Parameters.Add(new SqlParameter("@Name", item));
                cmd.Parameters.Add(new SqlParameter("@Course", attender.SelectedValue));
               SqlDataReader dtr = cmd.ExecuteReader();
 dtr.close();
            }
            con.Close();

答案 3 :(得分:0)

感谢您的帮助,这让我觉得打开/关闭我的连接有一些东西。

我像这样绕过它;

foreach (string item in attend)
            {
                con.Open();
                cmd.Parameters.Clear();
                cmd.Parameters.Add(new SqlParameter("@Name", item));
                cmd.Parameters.Add(new SqlParameter("@Course", attender.SelectedValue));
                cmd.ExecuteReader();
                con.Close();
            }

虽然多次打开和关闭连接可能效率很低。