ExecuteNonQuery()返回>0但插入数据未在Products表及DataTable中显示
VB.NET插入Access数据库成功提示但数据未显示的问题排查与修复
在VB.NET项目中执行添加产品的代码时,
ExecuteNonQuery()返回值大于0,程序弹出“SAVED PRODUCTS SUCCESSFULLY”提示,但插入的数据既未出现在Access数据库的Products表中,DataTable控件dtvInventory也未显示新数据。
原代码
Private Sub cmdAddProduct_Click(sender As Object, e As EventArgs) Handles cmdAddProduct.Click 'DATABASE CONNECITON Dim connection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Deeposdb.accdb") connection.Open() Dim cmd As New OleDbCommand("INSERT INTO Products (ProductName, Stock,CostPrice, UnitPrice) VALUES (?, ?, ?, ?)", connection) Dim validField As Boolean = ValidateFields(txtProductName.Text, numProductStock.Value, txtCostPrice.Text, txtSellingPrice.Text) If validField = True Then cmd.Parameters.Add("@ProductName", OleDbType.VarChar).Value = txtProductName.Text cmd.Parameters.Add("@Stock", OleDbType.Integer).Value = Convert.ToInt32(numProductStock.Value) cmd.Parameters.Add("@UnitPrice", OleDbType.Double).Value = Convert.ToDouble(txtSellingPrice.Text) cmd.Parameters.Add("@CostPrice", OleDbType.Double).Value = Convert.ToDouble(txtCostPrice.Text) Dim rowsAffected As Integer = cmd.ExecuteNonQuery() If rowsAffected > 0 Then MsgBox("SAVED PRODUCTS SUCCESSFULLY") dtvInventory.Update() Else MsgBox("SAVING PRODUCTS FAILED") End If Else MsgBox("COMPLETE ALL FIELDS TO PROCEED") End If connection.Close() End Sub
相关信息
- 数据库表信息:表名为
Products,字段包括自动生成主键的ProductID、ProductName(产品名称)、Stock(库存)、UnitPrice(单价)、SellingPrice(售价) - 控件对应关系:
txtProductName:产品名称文本框numProductStock:库存数字上下控件txtCostPrice:成本价文本框txtSellingPrice:售价文本框
问题根源分析
- 参数顺序不匹配:OleDb采用位置匹配而非参数名匹配,SQL语句字段顺序是
ProductName, Stock, CostPrice, UnitPrice,但代码中参数添加顺序是ProductName→Stock→UnitPrice→CostPrice,导致参数值错位,实际插入了错误的字段数据,甚至可能触发隐式数据回滚。 - 数据库文件路径偏差:调试时
|DataDirectory|指向项目的bin\Debug或bin\Release目录,你可能查看的是项目根目录下的原数据库文件,而非程序实际操作的副本。 - DataGridView未刷新数据源:
dtvInventory.Update()仅刷新控件显示,不会重新从数据库获取最新数据,必须重新查询并绑定数据源。
修复步骤
- 严格按照SQL语句的字段顺序添加参数
- 查看
bin\Debug目录下的数据库文件确认插入结果 - 新增数据加载方法,在插入成功后重新获取并绑定数据源
修复后的代码
Private Sub cmdAddProduct_Click(sender As Object, e As EventArgs) Handles cmdAddProduct.Click ' 使用Using自动管理连接资源,避免泄漏 Using connection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Deeposdb.accdb") connection.Open() ' 保持SQL字段顺序与参数顺序一致 Dim cmd As New OleDbCommand("INSERT INTO Products (ProductName, Stock, CostPrice, UnitPrice) VALUES (?, ?, ?, ?)", connection) Dim validField As Boolean = ValidateFields(txtProductName.Text, numProductStock.Value, txtCostPrice.Text, txtSellingPrice.Text) If validField Then ' 严格匹配SQL字段顺序添加参数 cmd.Parameters.Add("@ProductName", OleDbType.VarChar).Value = txtProductName.Text cmd.Parameters.Add("@Stock", OleDbType.Integer).Value = Convert.ToInt32(numProductStock.Value) cmd.Parameters.Add("@CostPrice", OleDbType.Double).Value = Convert.ToDouble(txtCostPrice.Text) cmd.Parameters.Add("@UnitPrice", OleDbType.Double).Value = Convert.ToDouble(txtSellingPrice.Text) Dim rowsAffected As Integer = cmd.ExecuteNonQuery() If rowsAffected > 0 Then MsgBox("产品保存成功") ' 重新加载数据到DataGridView LoadInventoryData() Else MsgBox("产品保存失败") End If Else MsgBox("请填写所有必填字段") End If End Using End Sub ' 封装数据加载方法 Private Sub LoadInventoryData() Using connection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Deeposdb.accdb") connection.Open() Dim adapter As New OleDbDataAdapter("SELECT * FROM Products", connection) Dim dt As New DataTable() adapter.Fill(dt) dtvInventory.DataSource = dt End Using End Sub
额外注意事项
- 始终用
Using语句管理数据库连接、命令等资源,确保自动释放 - 输入验证时,除了检查非空,还应验证数字格式(比如成本价、售价是否为有效数字)
- 可在
LoadInventoryData中添加异常捕获,处理数据库查询可能出现的错误
内容的提问来源于stack exchange,提问作者DEZZMOND
相关产品推荐
相关产品推荐

