如何在C#中用DataGridView值更新SQL表?解决输入字符串错误
Hey,我看了你遇到的输入字符串错误问题,结合你的代码分析下来,主要是几个细节没处理好,我帮你逐一排查并给出修复方案:
1. SQL语句拼接的空格坑
你的UPDATE语句拼接时,Total=@Total后面直接接WHERE,连个空格都没有,这会导致SQL语法直接炸锅——数据库会把它解析成Total=@TotalWHERE PO_No...,完全识别不了,这肯定会抛出输入格式类的错误。
修复方式: 给Total=@Total后面加个空格,或者用StringBuilder来拼接SQL,能彻底避免这类低级错误:
string query = "UPDATE TBL_PO_Cart " + "SET ISBN_No = @ISBN_No, OrderQuantity= @OrderQuantity, " + "UnitPrice= @UnitPrice, Total=@Total " + "WHERE PO_No = @PO_No";
2. 参数类型不匹配
OrderQuantity明明是整数类型,但你在添加SQL参数时居然用了SqlDbType.NVarChar!虽然你传入的是int值,但参数类型定义错误会触发数据转换异常,这也是输入字符串错误的常见诱因。
修复方式: 把OrderQuantity的参数类型改成SqlDbType.Int:
con.cmd.Parameters.Add(new SqlParameter("@OrderQuantity", SqlDbType.Int)); con.cmd.Parameters["@OrderQuantity"].Value = OrderQuantity;
3. DataGridView单元格值的空值处理
当DataGridView的单元格为空(DBNull)或者值没法转换成目标类型时,直接ToString()再Convert绝对会炸——比如单元格是空的,Convert.ToInt32(null)直接就抛出输入字符串错误了。
修复方式: 先判断单元格值是否为DBNull或null,再进行转换:
// 处理ISBN_No,为空就设空字符串 string isbn = dataGridView1.Rows[i].Cells[1].Value == DBNull.Value ? "" : dataGridView1.Rows[i].Cells[1].Value.ToString(); // 处理OrderQuantity,为空就设0(根据你的业务需求调整默认值) int orderQty = dataGridView1.Rows[i].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value); // UnitPrice和Total同理处理 decimal unitPrice = dataGridView1.Rows[i].Cells[3].Value == DBNull.Value ? 0 : Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value); decimal total = dataGridView1.Rows[i].Cells[4].Value == DBNull.Value ? 0 : Convert.ToDecimal(dataGridView1.Rows[i].Cells[4].Value);
4. 按钮点击事件的逻辑判断错误
你用了if (txtPONo.Text != "" || cmbsupID.Text != "" || ...),这里的逻辑是只要有一个字段不为空就执行更新,但实际需求应该是所有必填字段都不为空才执行吧?把||换成&&,不然必填字段为空时执行代码肯定会报错。
修复方式:
if (txtPONo.Text != "" && cmbsupID.Text != "" && date1.Text != "" && requireddate.Text != "" && txtgrandTotal.Text != "")
5. 跳过DataGridView的空行
如果你的DataGridView开了AllowUserToAddRows(默认是开启的),最后一行是空白的新行,直接循环Rows.Count-1会处理到这行空数据,引发转换错误。
修复方式: 循环时判断当前行是不是新行,是的话就跳过:
for (int i = 0; i < dataGridView1.Rows.Count; i++) { // 跳过自动添加的空白新行 if (dataGridView1.Rows[i].IsNewRow) continue; // 执行更新逻辑 }
完整修正后的代码
UpdatePOCartTable方法
public void UpdatePOCartTable(int PO_No, string ISBN_No, int OrderQuantity, decimal UnitPrice, decimal Total) { DynamicConnection con = new DynamicConnection(); con.mysqlconnection(); // 修复SQL语句的空格问题 string query = "UPDATE TBL_PO_Cart " + "SET ISBN_No = @ISBN_No, OrderQuantity= @OrderQuantity, " + "UnitPrice= @UnitPrice, Total=@Total " + "WHERE PO_No = @PO_No"; con.sqlquery(query); con.cmd.Parameters.Add(new SqlParameter("@PO_No", SqlDbType.Int)); con.cmd.Parameters["@PO_No"].Value = PO_No; con.cmd.Parameters.Add(new SqlParameter("@ISBN_No", SqlDbType.NVarChar)); con.cmd.Parameters["@ISBN_No"].Value = ISBN_No; // 修复OrderQuantity的参数类型 con.cmd.Parameters.Add(new SqlParameter("@OrderQuantity", SqlDbType.Int)); con.cmd.Parameters["@OrderQuantity"].Value = OrderQuantity; con.cmd.Parameters.Add(new SqlParameter("@UnitPrice", SqlDbType.Money)); con.cmd.Parameters["@UnitPrice"].Value = UnitPrice; con.cmd.Parameters.Add(new SqlParameter("@Total", SqlDbType.Money)); con.cmd.Parameters["@Total"].Value = Total; con.nonquery(); }
btnedit_Click事件
private void btnedit_Click(object sender, EventArgs e) { DynamicConnection con = new DynamicConnection(); try { // 修复逻辑判断的运算符 if (txtPONo.Text != "" && cmbsupID.Text != "" && date1.Text != "" && requireddate.Text != "" && txtgrandTotal.Text != "") { PurchaseOrder PO = new PurchaseOrder(); // 循环时跳过新行 for (int i = 0; i < dataGridView1.Rows.Count; i++) { if (dataGridView1.Rows[i].IsNewRow) continue; // 修复单元格值的空值处理 int poNo = Convert.ToInt32(txtPONo.Text); string isbn = dataGridView1.Rows[i].Cells[1].Value == DBNull.Value ? "" : dataGridView1.Rows[i].Cells[1].Value.ToString(); int orderQty = dataGridView1.Rows[i].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value); decimal unitPrice = dataGridView1.Rows[i].Cells[3].Value == DBNull.Value ? 0 : Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value); decimal total = dataGridView1.Rows[i].Cells[4].Value == DBNull.Value ? 0 : Convert.ToDecimal(dataGridView1.Rows[i].Cells[4].Value); PO.UpdatePOCartTable(poNo, isbn, orderQty, unitPrice, total); } } else { MessageBox.Show("Please Provide Details!"); } dataGridView1.Rows.Clear(); ClearData(); retviewPO_No(); MessageBox.Show("Record Updated Successfully"); } catch (Exception ex) { MessageBox.Show("Error Occured: " + ex.Message); } }
内容的提问来源于stack exchange,提问作者Kith

