C#中SqlDataAdapter.Fill引发InvalidOperationException未处理错误求助
问题分析与解决
直接触发InvalidOperationException的原因
- 空值校验顺序错误:你先执行数据库查询
sdadap.Fill(dtab),再做输入空值校验。若用户输入为空(比如txtBarcode.Text为空),生成的查询语句会出现语法隐患,且**else后多了分号**,导致空值校验逻辑失效,无论输入是否为空都会执行后续代码,加重异常触发概率。 - 下拉框选中项未处理:如果
cmbType未选中任何项,SelectedItem为null,直接拼接进SQL会导致语法错误,触发数据库操作异常。 - SQL拼接的语法与安全隐患:直接拼接用户输入到SQL语句中,不仅存在SQL注入风险,还会因输入包含单引号等特殊字符导致SQL语法错误。
修正后的代码
private void btnAddUpdate_Click(object sender, EventArgs e) { // 先做输入校验,提前拦截无效输入 if (string.IsNullOrWhiteSpace(txtBarcode.Text) || string.IsNullOrWhiteSpace(txtItem.Text) || cmbType.SelectedItem == null || string.IsNullOrWhiteSpace(txtPrice.Text)) { MessageBox.Show("Please complete the missing data.", "Error...", MessageBoxButtons.OK, MessageBoxIcon.Error); return; // 校验不通过直接返回,不执行后续数据库操作 } // 使用参数化SQL,避免注入和语法错误 string insertQuery = "INSERT INTO Items(Barcode, Item, Type, Price) VALUES(@Barcode, @Item, @Type, @Price)"; string checkQuery = "SELECT Barcode FROM Items WHERE Barcode = @Barcode"; // using语句自动管理连接生命周期,避免资源泄漏 using (SqlConnection conn = new SqlConnection(conString)) { try { // 检查条码是否已存在(按需保留) SqlDataAdapter sdadap = new SqlDataAdapter(checkQuery, conn); sdadap.SelectCommand.Parameters.AddWithValue("@Barcode", txtBarcode.Text); DataTable dtab = new DataTable(); sdadap.Fill(dtab); if (dtab.Rows.Count > 0) { MessageBox.Show("This barcode already exists.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 执行插入操作 SqlCommand runquery = new SqlCommand(insertQuery, conn); runquery.Parameters.AddWithValue("@Barcode", txtBarcode.Text); runquery.Parameters.AddWithValue("@Item", txtItem.Text); runquery.Parameters.AddWithValue("@Type", cmbType.SelectedItem.ToString()); // 处理Price字段的数值转换(若字段为数值类型) if (!decimal.TryParse(txtPrice.Text, out decimal price)) { MessageBox.Show("Please enter a valid price.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } runquery.Parameters.AddWithValue("@Price", price); conn.Open(); runquery.ExecuteNonQuery(); MessageBox.Show("Good added", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Error: {ex.Message}"); } // using块自动关闭连接,无需手动调用conn.Close() } }
关键修正说明
- 调整校验顺序:先做输入合法性校验,不通过直接返回,避免无效数据库操作。
- 修复语法错误:移除
else后的分号,让空值校验分支逻辑生效。 - 参数化SQL:彻底避免SQL注入,同时解决特殊字符导致的语法错误。
- 自动管理连接:用
using语句自动释放数据库连接资源,避免连接泄漏。 - 处理下拉框空值:先判断
cmbType.SelectedItem是否为null,再转换为字符串。 - 数值类型转换:针对
Price这类数值型字段,将输入文本转换为对应类型,避免类型不匹配异常。 - 重复条码检查:利用查询结果判断条码是否已存在,避免重复插入(按需保留)。
内容的提问来源于stack exchange,提问作者nandana2 nandana
相关产品推荐
相关产品推荐

