C# 为每个 DataGridView 行更新数据库

标签 c# datagridview

我想使用“更新”按钮为 DataGridView 中的每一行更新数据库中的表。这是以下更新按钮代码:

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

当我按下更新按钮时,只有 DataGridViews 的第一行在数据库中被成功更新但其他行没有更新。 它还会返回一些错误,详细信息如下:

The variable name '@HFP' has already been declared. Variable names must be unique within a query batch or stored procedure.

我曾尝试搜索和谷歌搜索,但从未找到合适的。

请帮我解决这个问题。 谢谢。

最佳答案

您需要在每个循环中清除 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 block 内声明和初始化。此外,为了使您的代码更加健壮,我添加了一个事务,以确保您的所有记录都写入数据库,或者在发生故障时不会写入任何记录。循环末尾的 SqlTransaction.Commit 可确保这一点。

最后,我不知道接收参数值的字段的数据类型。您需要根据数据表中列的数据类型在创建参数时更改 SqlDbType。

关于C# 为每个 DataGridView 行更新数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35125644/

相关文章:

c# - 并非所有代码路径都会返回一个值 - 但它们会

c# - 如何将列表框中的记录显示到数据表或 GridView ?

c# - 删除dataGridView的最后一个空行

c# - 设置 DataGridView ComboBoxColumn 的 DropDown 列表宽度 - WinForms

.net - 为什么我的 DataGridView 拒绝显示底部数据以及如何修复它?

c# - 如何在 .NET 2.0 中创建自定义集合

c# - 为项目列表选择正确的控件

c# - 自承载 WCF 服务中的 HTTP 413 请求实体太大

c# - 从 Word 文档中获取列表编号?

c# - datagridview单元格鼠标悬停背景色更改