如何在每次迭代中重用 SqlCommand 参数?
Posted
技术标签:
【中文标题】如何在每次迭代中重用 SqlCommand 参数?【英文标题】:How to reuse SqlCommand parameter through every iteration? 【发布时间】:2012-08-19 11:20:09 【问题描述】:我想为我的数据库实现一个简单的删除按钮。事件方法看起来像这样:
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 已被声明。变量名在内部必须是唯一的 查询批处理或存储过程。
有没有办法重用这个变量?
【问题讨论】:
【参考方案1】:错误是因为您在循环的每次迭代中一次又一次地添加相同的参数。
我会将该代码移动到一个单独的方法中,以便我可以根据需要从多个地方调用它。
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
【讨论】:
【参考方案2】:Parameters.AddWithValue
向命令添加一个新参数。由于您是在具有相同名称的循环中执行此操作,因此您会收到异常“变量名称必须是唯一的”。
所以你只需要一个参数,在循环之前添加它,在循环中只改变它的值。
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();
。然后您也可以在循环中添加参数,而无需两次创建相同的参数。
【讨论】:
【参考方案3】:而不是:
command.Parameters.AddWithValue("@id", rowUserID);
使用类似的东西:
System.Data.SqlClient.SqlParameter p = new System.Data.SqlClient.SqlParameter();
在 foreach 之外,只需在循环内手动设置:
p.ParameterName = "@ID";
p.Value = rowUserID;
【讨论】:
【参考方案4】:我会用这个:
public static class DbExtensions
public static void AddParameter(SQLiteCommand command, string name, DbType type, object value)
var param = new SQLiteParameter(name, type);
param.Value = value;
command.Parameters.Add(param);
然后,调用它:
DbExtensions.AddParameter(command, "@" + fieldOfSearch[i], DbType.String, value[i]);
【讨论】:
以上是关于如何在每次迭代中重用 SqlCommand 参数?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SqlCommand 创建具有参数化数据库名称的数据库?
如何在for循环中等待每次迭代并在nodeJS中将响应作为API响应返回