C#更新Access数据库无效果求助:代码执行正常但未更新
问题排查与修复方案
我仔细看了你的代码,发现几个关键问题导致数据库没更新,咱们一个个拆解:
1. 最致命的问题:OleDb参数顺序不匹配
OleDb和SqlServer的参数绑定逻辑不一样——它不按参数名称匹配,而是严格遵循SQL语句里参数出现的顺序来对应你添加的参数。
看你的SQL语句,参数出现的顺序是:@meals → @price → @picture → @description → @id,但你添加参数的顺序却是先加@id,再依次加其他参数,这就导致WHERE子句里的@id实际拿到的是meal.Text的值,根本找不到对应的行,数据库自然不会有任何变化!
2. 错误用UPDATE命令填充DataTable
你执行完cmd.ExecuteNonQuery()之后,又用同一个cmd(此时CommandText是UPDATE语句)去调用adapter.Fill(dt)——UPDATE语句不会返回任何数据集,这一步完全无效,还可能引发隐性异常。
3. 连接管理不规范
你多次手动调用con.Close(),而且没有用using语句自动管理连接生命周期,这样很容易导致连接泄漏,也可能因为重复关闭引发错误。
4. 更新后未刷新DataGridView
就算数据库更新成功了,你也没有重新查询最新数据绑定到DataGridView,界面上还是旧数据,会让你误以为更新没生效。
修复后的完整代码
我把这些问题都修正了,你可以直接测试:
private void update_Click(object sender, EventArgs e) { // 用using自动管理连接,无需手动关闭 using (OleDbConnection con = new OleDbConnection(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Users\sherilyn & justine\Documents\Visual Studio 2015\Projects\jollibee4\jollibee4\jollibee.accdb")) { con.Open(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = con; string id = dataGridView1.SelectedRows[0].Cells[0].Value.ToString(); int id1 = int.Parse(id); try { // 用switch简化分支逻辑 switch (database.selectedIndex) { case 0: cmd.CommandText = "update Breakfast_Meals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 1: cmd.CommandText = "update Burger_Sandwhich_Meals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 2: cmd.CommandText = "update Chicken_Meals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 3: cmd.CommandText = "update Dessert set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 4: cmd.CommandText = "update Kids_Meals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 5: cmd.CommandText = "update RiceMeals_NoodlesMeals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 6: cmd.CommandText = "update Side_Items set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; case 7: cmd.CommandText = "update Value_Meals set [Meals] = @meals, [Price] = @price, [Picture] = @picture, [Description] = @description WHERE [Item ID]=@id"; break; default: MessageBox.Show("Invalid category selection!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 严格按照SQL语句中参数的顺序添加! cmd.Parameters.AddWithValue("@meals", meal.Text); int mealPrice; // 增加价格输入验证,避免非数字引发异常 if (!int.TryParse(price.Text, out mealPrice)) { MessageBox.Show("Please enter a valid number for price!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } cmd.Parameters.AddWithValue("@price", mealPrice); cmd.Parameters.AddWithValue("@picture", savePhoto()); cmd.Parameters.AddWithValue("@description", description.Text); cmd.Parameters.AddWithValue("@id", id1); DialogResult dialogResult = MessageBox.Show("Are you sure you want to change the data?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (dialogResult == DialogResult.Yes) { // 执行更新并获取受影响行数,用来验证是否更新成功 int affectedRows = cmd.ExecuteNonQuery(); if (affectedRows == 0) { MessageBox.Show("No rows updated - check if the Item ID exists!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { return; } // 更新完成后,重新查询数据刷新DataGridView DataTable dt = new DataTable(); OleDbCommand selectCmd = new OleDbCommand(); selectCmd.Connection = con; // 重新查询当前选中分类的最新数据 switch (database.selectedIndex) { case 0: selectCmd.CommandText = "SELECT * FROM Breakfast_Meals"; break; case 1: selectCmd.CommandText = "SELECT * FROM Burger_Sandwhich_Meals"; break; case 2: selectCmd.CommandText = "SELECT * FROM Chicken_Meals"; break; case 3: selectCmd.CommandText = "SELECT * FROM Dessert"; break; case 4: selectCmd.CommandText = "SELECT * FROM Kids_Meals"; break; case 5: selectCmd.CommandText = "SELECT * FROM RiceMeals_NoodlesMeals"; break; case 6: selectCmd.CommandText = "SELECT * FROM Side_Items"; break; case 7: selectCmd.CommandText = "SELECT * FROM Value_Meals"; break; } OleDbDataAdapter adapter = new OleDbDataAdapter(selectCmd); adapter.Fill(dt); dataGridView1.DataSource = dt; // 也可以直接调用你的自定义方法刷新数据 database_onItemSelected(sender, e); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // using块结束后会自动关闭并释放连接 } }
额外注意事项
- 确认
savePhoto()返回的是Access支持的类型:如果是存储图片,应该返回byte[]字节数组;如果存的是图片路径,那数据库里只会保存字符串路径。 - 建议对所有用户输入(比如
meal.Text、description.Text)做空值或格式验证,避免异常。 - 可以在更新后检查
affectedRows的值,如果为0,说明没有匹配到要更新的行,可能是Item ID错误,可以给用户明确提示。
内容的提问来源于stack exchange,提问作者Sherilyn Reyes
相关产品推荐
相关产品推荐

