SQLiteDataAdapter Update方法不生效问题求助
问题分析与解决
你的代码存在几个关键问题,导致数据库未发生更新:
DataSet无数据变更,Update无执行依据
DataAdapter.Update()是根据DataSet中数据的变更状态(新增、修改、删除)来触发对应SQL操作的。你用Fill()读取数据到DataSet后,没有修改其中任何数据,直接调用Update,自然不会执行任何数据库更新。UpdateCommand逻辑混乱
你先通过SQLiteCommandBuilder生成了自动更新命令,随后又用手动拼接的SQLCommand覆盖了它,但这个手动命令并未执行(没有调用cmd.ExecuteNonQuery()),反而打乱了DataAdapter的更新逻辑。存在SQL注入风险
直接用字符串拼接SQL语句,不仅容易因数据类型出错,还会引发严重的SQL注入漏洞。
修正后的代码方案
方案一:通过修改DataSet触发自动更新(推荐,符合DataAdapter设计逻辑)
private void potrdi_Click(object sender, EventArgs e) { if (!int.TryParse(idFilma.Text, out int id)) { MessageBox.Show("请输入有效的影片ID"); return; } if (!double.TryParse(novaOcena.Text, out double nova)) { MessageBox.Show("请输入有效的评分"); return; } DataSet ds = new DataSet(); string povNiz = @"Data Source=C:\Users\filmi.sqlite;Version=3"; using (SQLiteConnection povezava = new SQLiteConnection(povNiz)) { // 参数化查询避免SQL注入 string selectSql = "SELECT id, naslov, ocena FROM filmi WHERE id = @Id"; SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(selectSql, povezava); dataAdapter.SelectCommand.Parameters.AddWithValue("@Id", id); dataAdapter.Fill(ds); if (ds.Tables[0].Rows.Count == 0) { MessageBox.Show("未找到对应影片"); return; } // 修改DataSet中的数据,标记为变更状态 DataRow row = ds.Tables[0].Rows[0]; row["ocena"] = nova; // 自动生成更新命令并执行 SQLiteCommandBuilder builder = new SQLiteCommandBuilder(dataAdapter); int affectedRows = dataAdapter.Update(ds); if (affectedRows > 0) { MessageBox.Show("更新成功"); prikazPodatkov2.DataSource = ds.Tables[0]; } else { MessageBox.Show("更新失败"); } } }
方案二:直接执行手动更新SQL(适合简单场景)
如果不需要维护DataSet的数据状态,直接执行SQL命令更高效:
private void potrdi_Click(object sender, EventArgs e) { if (!int.TryParse(idFilma.Text, out int id)) { MessageBox.Show("请输入有效的影片ID"); return; } if (!double.TryParse(novaOcena.Text, out double nova)) { MessageBox.Show("请输入有效的评分"); return; } string povNiz = @"Data Source=C:\Users\filmi.sqlite;Version=3"; using (SQLiteConnection povezava = new SQLiteConnection(povNiz)) { povezava.Open(); // 参数化查询 string updateSql = "UPDATE filmi SET ocena = @NovaOcena WHERE id = @Id"; using (SQLiteCommand cmd = new SQLiteCommand(updateSql, povezava)) { cmd.Parameters.AddWithValue("@NovaOcena", nova); cmd.Parameters.AddWithValue("@Id", id); int affectedRows = cmd.ExecuteNonQuery(); if (affectedRows > 0) { MessageBox.Show("更新成功"); // 重新查询数据刷新界面 string selectSql = "SELECT id, naslov, ocena FROM filmi WHERE id = @Id"; using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(selectSql, povezava)) { dataAdapter.SelectCommand.Parameters.AddWithValue("@Id", id); DataSet ds = new DataSet(); dataAdapter.Fill(ds); prikazPodatkov2.DataSource = ds.Tables[0]; } } else { MessageBox.Show("未找到对应影片或无数据变更"); } } } }
关键注意事项
- 必须使用参数化查询,杜绝SQL注入风险,同时避免数据类型转换错误。
- 用
using语句自动释放数据库连接等资源,防止资源泄漏。 - 更新后若需刷新界面,需重新查询数据库或使用已变更的DataSet。
内容的提问来源于stack exchange,提问作者Payana
相关产品推荐
相关产品推荐

