2012-08-23 107 views
15

自分のデータベースに単純な削除ボタンを実装したいと思います。イベントメソッドは次のようなものになります。繰り返しごとにSqlCommandパラメータを再利用する方法は?

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が宣言されました。変数名は、クエリバッチまたはストアドプロシージャ 内で一意である必要があります。

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

答えて

42

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; 
    // ... 
} 

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

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 
    } 
} 
3

むしろより:

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

使用のようなもの:foreachの外

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

、ちょうどループ内で手動設定:

p.ParameterName = "@ID"; 
p.Value = rowUserID; 
関連する問題