22

データベースに単純な削除ボタンを実装したいと考えています。イベント メソッドは次のようになります。

private void btnDeleteUser_Click(object sender, EventArgs e)
{
    if (MessageBox.Show("Are you sure?", "delete users",MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
    {
        command = new SqlCommand();
        try
        {
            User.connection.Open();
            command.Connection = User.connection;
            command.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
            int flag;
            foreach (DataGridViewRow row in dgvUsers.SelectedRows)
            {
                int selectedIndex = row.Index;
                int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());

                command.Parameters.AddWithValue("@id", rowUserID);
                flag = command.ExecuteNonQuery();
                if (flag == 1) { MessageBox.Show("Success!"); }

                dgvUsers.Rows.Remove(row);
            }
        }
        catch (SqlException ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        finally
        {
            if (ConnectionState.Open.Equals(User.connection.State)) 
               User.connection.Close();
        }
    }
    else
    {
        return;
    }
}

しかし、私はこのメッセージを受け取ります:

変数 @id が宣言されています。変数名は、クエリ バッチまたはストアド プロシージャ内で一意である必要があります。

この変数を再利用する方法はありますか?

4

4 に答える 4

56

Parameters.AddWithValueコマンドに新しいパラメータを追加します。同じ名前のループでそれを行っているため、「変数名は一意でなければなりません」という例外が発生します。

したがって、必要なパラメーターは 1 つだけです。それをループの前に追加し、ループ内の値のみを変更します。

command.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
command.Parameters.Add("@id", SqlDbType.Int);
int flag;
foreach (DataGridViewRow row in dgvUsers.SelectedRows)
{
    int selectedIndex = row.Index;
    int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());
    command.Parameters["@id"].Value = rowUserID;
    // ...
}

別の方法は、command.Parameters.Clear();最初に使用することです。次に、同じパラメーターを 2 回作成することなく、ループにパラメーターを追加することもできます。

于 2012-08-23T21:28:57.853 に答える
4

それよりも:

command.Parameters.AddWithValue("@id", rowUserID);

次のようなものを使用します。

System.Data.SqlClient.SqlParameter p = new System.Data.SqlClient.SqlParameter();

foreach の外側で、ループ内で手動で設定するだけです。

p.ParameterName = "@ID";
p.Value = rowUserID;
于 2012-08-23T21:29:57.737 に答える
0

エラーは、ループの各反復で同じパラメーターを何度も追加しているためです。

そのコードを別のメソッドに移動して、必要に応じて複数の場所から呼び出すことができるようにします。

public bool DeleteUser(int userId)
{
    string connString = "your connectionstring";
    try
    {
      using (var conn = new SqlConnection(connString))
      {
        using (var cmd = new SqlCommand())
        {
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
            cmd.Parameters.AddWithValue("@id", userId);
            conn.Open();
            cmd.ExecuteNonQuery();
            return true;
        }
      }
    }
    catch(Exception ex)
    {
      //Log the Error here for Debugging
      return false;
    }

}

次に、このように呼び出します

 foreach (DataGridViewRow row in dgvUsers.SelectedRows)
 {
   int selectedIndex = row.Index;
   if(dgvUsers[0,selectedIndex]!=null)
   {
     int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());
     var result=DeleteUser(rowUserID)
   }
   else
   {
      //Not able to get the ID. Show error message to user
   } 
 }
于 2012-08-23T21:28:37.893 に答える