2012-08-23 30 views
15

Tôi muốn thực hiện một nút xóa đơn giản cho cơ sở dữ liệu của tôi. Phương thức sự kiện trông giống như sau:Làm thế nào để tái sử dụng tham số SqlCommand thông qua mỗi lần lặp?

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

nhưng tôi nhận được tin nhắn này:

Một @ id biến đã được công bố. Tên biến phải là duy nhất trong vòng lô truy vấn hoặc quy trình được lưu trữ.

Có cách nào để sử dụng lại biến này không?

Trả lời

42

Parameters.AddWithValue cho biết thêm một thông số mới cho lệnh. Vì bạn đang làm điều đó trong một vòng lặp có cùng tên, bạn sẽ nhận được ngoại lệ "Tên biến phải là duy nhất".

Vì vậy, bạn chỉ cần một tham số, thêm thông số đó trước vòng lặp và chỉ thay đổi giá trị của nó trong vòng lặp.

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

Một cách khác là sử dụng command.Parameters.Clear(); trước tiên. Sau đó, bạn cũng có thể thêm (các) tham số trong vòng lặp mà không tạo tham số giống nhau hai lần.

0

Lỗi là vì bạn đang thêm cùng một tham số vào mỗi lần lặp của vòng lặp.

Tôi sẽ di chuyển mã đó sang một phương pháp riêng biệt để tôi có thể gọi nó từ nhiều nơi nếu cần.

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

} 

Sau đó gọi nó như thế này

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

Thay vì:

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

Sử dụng một cái gì đó như:

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

Bên ngoài foreach, và chỉ cần đặt tay bên trong vòng lặp:

p.ParameterName = "@ID"; 
p.Value = rowUserID; 
Các vấn đề liên quan