2012-08-23 13 views
15

Chcę zaimplementować prosty przycisk usuwania dla mojej bazy danych. Metoda wydarzenie wygląda mniej więcej tak:Jak ponownie użyć parametru SqlCommand w każdej iteracji?

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

ale dostaję komunikat:

Zmienna @id została zadeklarowana. Nazwy zmiennych muszą być unikatowe w ramach kwerendy wsadowej lub procedury składowanej.

Czy istnieje sposób na ponowne użycie tej zmiennej?

Odpowiedz

42

Parameters.AddWithValue dodaje nowy parametr do komendy. Ponieważ robisz to w pętli o tej samej nazwie, otrzymujesz wyjątek "Nazwy zmiennych muszą być unikalne".

Więc potrzebujesz tylko jednego parametru, dodaj go przed pętlą i zmień tylko jego wartość w pętli.

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

Innym sposobem jest użycie najpierw command.Parameters.Clear();. Następnie możesz dodać parametry w pętli bez dwukrotnego tworzenia tego samego parametru.

0

Błąd polega na tym, że dodajesz ten sam parametr wielokrotnie w każdej iteracji pętli.

Chciałbym przenieść ten kod do oddzielnej metody, aby móc wywołać go z wielu miejsc w razie potrzeby.

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

} 

Następnie nazwać jak ten

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

Zamiast:

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

użyć coś jak:

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

Poza foreach i wystarczy ustawić ręcznie wewnątrz pętli:

p.ParameterName = "@ID"; 
p.Value = rowUserID; 
Powiązane problemy