C# WinForm中为何无法通过SQL查询向MS Access插入数值类型数据
问题核心根因
- 错误的SQL拼接逻辑,把数值类型的字段值错误加了单引号包裹
当前代码给所有字段值都套了单引号拼接,ProductName本身是字符串类型,用单引号包裹是合法的,所以能正常写入;但Quantity、Weight(g)是数值类型,带单引号的值会被解析为字符串,和字段的数值类型不匹配,直接触发类型转换异常。你之前尝试int.Parse没生效,大概率是转完数值后拼接SQL的时候,还是给转好的值套了单引号,等于没做类型区分。 - 特殊字符的字段名没有做SQL转义
Weight(g)字段名里带括号,属于Jet SQL的保留语法字符,如果不在SQL语句里用方括号把字段名包裹成[Weight(g)],解析器会直接把括号当成SQL语法标记,抛出语法错误,哪怕类型值是对的也跑不通。
针对性修复方案
优先使用参数化查询,从根源上解决类型不匹配、特殊字符转义、SQL注入的问题,参考改造后的代码:
private void cmdAdd_Click(object sender, EventArgs e) { // 先做输入合法性校验,避免非法文本触发类型转换异常 if (!int.TryParse(txtQuantity.Text, out int productQuantity)) { MessageBox.Show("请输入合法的整数数量"); return; } if (!decimal.TryParse(txtWeight.Text, out decimal productWeight)) { MessageBox.Show("请输入合法的重量数值"); return; } try { // 连接对象随用随建,通过using自动释放资源,避免长期持有连接造成泄漏 using (var conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Folder\Database.mdb;Persist Security Info=False;")) { conn.Open(); var insertCmd = new OleDbCommand { Connection = conn, // 带特殊符号的字段名用方括号包裹,参数位置用?占位(OLEDB驱动不支持命名参数) CommandText = "INSERT INTO Products (ProductName, Quantity, [Weight(g)]) VALUES (?, ?, ?)" }; // 按SQL里占位符的顺序添加对应类型的参数,不需要手动处理引号包裹 insertCmd.Parameters.AddWithValue("nameParam", txtName.Text.Trim()); insertCmd.Parameters.AddWithValue("qtyParam", productQuantity); insertCmd.Parameters.AddWithValue("weightParam", productWeight); insertCmd.ExecuteNonQuery(); MessageBox.Show("Data saved"); } } catch (Exception ex) { MessageBox.Show("Error:" + ex.Message); } }
关键注意事项
- *OLEDB驱动的参数匹配是按添加顺序生效的,和参数名无关,所以添加参数的顺序必须和SQL语句里
?的位置一一对应,不能随意调换 - 手动拼接SQL的场景下,字符串类型的值才需要用单引号包裹,数值、日期类型的值不能加单引号,否则会触发类型不匹配异常——但不推荐手动拼接的方式,有SQL注入风险
- 不要把
OleDbConnection作为Form级别的长期成员变量,数据库连接是稀缺资源,长期持有会造成连接池耗尽、Access数据文件锁死等问题
内容的提问来源于stack exchange,提问作者Gianella
相关产品推荐
相关产品推荐

