C# 为每个 DataGridView 行更新数据库
本文关键字:更新 数据库 DataGridView | 更新日期: 2023-09-27 18:32:46
我想使用"更新"按钮更新数据库中每一行的表。这是以下更新按钮代码:
private void btUpdate_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection(con);
cn.Open();
SqlCommand cmdUpdate = new SqlCommand("UPDATE OINV SET U_IDU_HFP = @HFP, U_IDU_FAKTURPAJAK = @FP, U_IDU_FPDATE = @FPDATE WHERE DocEntry = @DocEntry;", cn);
foreach (DataGridViewRow item in dgvInputPKP.Rows)
{
cmdUpdate.Parameters.AddWithValue("@HFP", item.Cells[10].Value);
cmdUpdate.Parameters.AddWithValue("@FP", item.Cells[11].Value);
cmdUpdate.Parameters.AddWithValue("@FPDATE", item.Cells[9].Value);
cmdUpdate.Parameters.AddWithValue("@DocEntry", item.Cells[1].Value);
cmdUpdate.ExecuteNonQuery();
}
MessageBox.Show("Record Updated Successfully");
cn.Close();
}
当我按下更新按钮时,只有 DataGridView 中的第一行在数据库中成功更新,但其他行没有。它还返回一些错误,其中包含以下详细信息:
变量名称"@HFP"已声明。变量名称在查询批处理或存储过程中必须是唯一的。
我试图搜索和谷歌搜索,但从未找到合适的。
请帮我解决这个问题。谢谢。
您需要在每个循环中清除 Command.Parameters 集合
foreach (DataGridViewRow item in dgvInputPKP.Rows)
{
cmdUpdate.Parameters.Clear();
....
cmdUpdate.ExecuteNonQuery();
}
但是,这里有几件事可以做,以优化和使您的代码更安全并消除弱点。
using(SqlConnection cn = new SqlConnection(con))
using(SqlCommand cmdUpdate = new SqlCommand("UPDATE OINV SET U_IDU_HFP = @HFP, U_IDU_FAKTURPAJAK = @FP, U_IDU_FPDATE = @FPDATE WHERE DocEntry = @DocEntry;", cn))
{
cn.Open();
using(SqlTransaction tr = cn.BeginTrasaction())
{
cmdUpdate.Transaction = tr;
cmdUpdate.Parameters.Add("@HFP", SqlDbType.NVarChar);
cmdUpdate.Parameters.Add("@FP", SqlDbType.NVarChar);
cmdUpdate.Parameters.Add("@FPDATE", SqlDbType.NVarChar);
cmdUpdate.Parameters.Add("@DocEntry", SqlDbType.NVarChar);
foreach (DataGridViewRow item in dgvInputPKP.Rows)
{
cmdUpdate.Parameters["@HFP"].Value = item.Cells[10].Value;
cmdUpdate.Parameters["@FP"].Value = item.Cells[11].Value;
cmdUpdate.Parameters["@FPDATE"].Value = item.Cells[9].Value;
cmdUpdate.Parameters["@DocEntry"].Value = item.Cells[1].Value;
cmdUpdate.ExecuteNonQuery();
}
tr.Commit();
}
}
MessageBox.Show("Record Updated Successfully");
可以在进入循环之前声明参数集合,而在循环中仅更新值。另请注意,命令和连接是一次性对象,应在 using 块中声明和初始化。此外,为了使您的代码更加健壮,我添加了一个事务,以确保您的所有记录都写入数据库,或者在发生故障时不会写入任何记录。循环末尾的 SqlTransaction.Commit 确保了这一点。
最后,我不知道接收参数值的字段的数据类型。您需要根据数据表中列的数据类型在创建参数时更改 SqlDbType。
由于您使用 AddWithValue
,此方法尝试在每次迭代中一遍又一遍地添加参数及其值。
这就是第一次迭代工作的原因,但在第二次迭代中,您的命令已经具有这些参数定义,并且您仍然尝试再次添加它们。您会收到此错误消息。
只需使用SqlParameterCollection.Clear
方法即可使用您的 foreach 状态网络顶部;
foreach (DataGridViewRow item in dgvInputPKP.Rows)
{
cmdUpdate.Parameters.Clear();
cmdUpdate.Parameters.AddWithValue("@HFP", item.Cells[10].Value);
cmdUpdate.Parameters.AddWithValue("@FP", item.Cells[11].Value);
cmdUpdate.Parameters.AddWithValue("@FPDATE", item.Cells[9].Value);
cmdUpdate.Parameters.AddWithValue("@DocEntry", item.Cells[1].Value);
cmdUpdate.ExecuteNonQuery();
}
顺便说一句,不要尽可能多地使用AddWithValue
。它有时可能会产生意想不到和令人惊讶的结果。使用Add
方法重载指定参数类型及其大小。
还可以使用 using
语句自动释放连接和命令,而不是手动调用Close
或Dispose
方法。
将整个 SQL 命令放入 foreach 中。