0

私が持っているのは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();

これは、リスト内の 1 つの項目のみをチェックすると完全に機能し、複数の項目をチェックすると失敗します。

エラーメッセージは次のとおりです。

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

コマンドなどの変数名を変更しようとしましたが、どこで a が開いているのかわかりませんDataReader。以前にこのエラーに遭遇したことはありません。

4

4 に答える 4

1

接続を開くときに次のアプローチを試してください

(SqlConnection conn = new SqlConnection()) を使用
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = 新しい SqlDataAdapter(Sqlmd);
   //...等
}
于 2013-06-17T10:56:40.850 に答える
1

ループ内で使用するため

cmd.ExecuteReader();

これは、最初にループが SqlDataReader を開き (割り当てられていませんが、まだそこにあります)、ループを再実行すると、未使用の SqlDataReader がまだ接続をブロックしています。

代わりに使用

cmd.ExecuteNonQuery();

本当に 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();
        }
     }

また、パラメーターをループの外側で宣言して追加し、ループの内側の値のみを変更することもできます。これで少し速度が上がります

于 2013-06-17T10:58:49.357 に答える