如何将WPF DataGrid数据插入两张SQL表并解决WHERE语法错误
问题根因
你遇到的语法错误核心原因是:标准SQL的INSERT语句语法不支持WHERE子句。INSERT的作用是新增全新的数据行,不存在对已有行做条件匹配的逻辑,你写的带WHERE的INSERT完全不符合SQL语法规范,所以数据库会直接在WHERE位置报语法错误。
结合你的需求描述,你实际要实现的是匹配productlist表中已有的、brandname等于当前采购行name值的记录,同步更新对应字段,而非新增一行数据,这种场景应该使用UPDATE语句而非INSERT。
修复方案
1. 替换错误语句为正确的UPDATE语法
把你原来编写的cmd1对应SQL替换为UPDATE语句即可,正确逻辑是匹配brandname条件后更新stock、net(对应你要同步的pack、total值)字段:
// 注意:如果pack代表本次采购入库数量,需要在原有库存基础上累加,就把stock = @pack改成stock = stock + @pack // net字段如果是累计采购金额也同理做累加,如果是记录最新进价直接赋值即可 SqlCommand cmd1 = new SqlCommand("UPDATE productlist SET stock = @pack, net = @total WHERE brandname = @name1", con); cmd1.Parameters.AddWithValue("@name1", (purrecord.Columns[0].GetCellContent(purrecord.Items[i]) as TextBlock).Text); cmd1.Parameters.AddWithValue("@pack", (purrecord.Columns[1].GetCellContent(purrecord.Items[i]) as TextBlock).Text); cmd1.Parameters.AddWithValue("@total", (purrecord.Columns[4].GetCellContent(purrecord.Items[i]) as TextBlock).Text); cmd1.ExecuteNonQuery();
业务逻辑适配提示:采购入库场景下库存、金额字段通常需要做累加而非直接覆盖,直接赋值会清空历史库存/金额数据,请根据实际业务规则调整SET后的字段计算逻辑。
2. 修复原有代码的SQL注入风险
你原来写的purchases表插入逻辑存在严重安全隐患,postid1.Text、crnttime、company.SelectedItem三个值是直接拼接在SQL字符串中的,没有走参数化传值,可能被恶意输入注入非法SQL语句,也容易出现特殊字符转义错误,建议全部改为参数化传值,修正示例:
SqlCommand cmd = new SqlCommand("INSERT into purchases (id, name, pack, piece, Rate, total, discountper, discountrs, bonus, totaldisc, time, company) values(@postId, @name, @pack, @piece, @Rate, @total, @discountper, @discountrs, @bonus, @totaldisc, @crntTime, @company)", con); // 将原拼接的字段全部加入参数 cmd.Parameters.AddWithValue("@postId", postid1.Text); cmd.Parameters.AddWithValue("@crntTime", crnttime); cmd.Parameters.AddWithValue("@company", company.SelectedItem); // 原有其余参数保持不变即可 cmd.Parameters.AddWithValue("@name", (purrecord.Columns[0].GetCellContent(purrecord.Items[i]) as TextBlock).Text); // ... 其余参数省略 cmd.ExecuteNonQuery();
3. 特殊场景适配(不存在则新增、存在则更新)
如果你的业务要求productlist中没有对应品牌商品时自动新增一条记录,存在时则更新,无需分开写INSERT和UPDATE,可以直接使用SQL Server支持的MERGE语法实现UPSERT逻辑:
MERGE productlist AS target USING (SELECT @name1 AS brandname, @pack AS stock, @total AS net) AS source ON target.brandname = source.brandname WHEN MATCHED THEN UPDATE SET target.stock = source.stock, target.net = source.net -- 需累加时改为target.stock + source.stock即可 WHEN NOT MATCHED THEN INSERT (brandname, stock, net) VALUES (source.brandname, source.stock, source.net);
常见踩坑提醒
- 不要依赖
AddWithValue的隐式类型转换,建议明确指定参数的SqlDbType,库存、金额这类数值字段不要直接传字符串,转成对应的int/decimal类型再传参,避免出现类型转换错误、精度丢失、查询不命中的问题。 - 数据库操作记得用
using语句包裹SqlConnection、SqlCommand等对象,确保非托管资源及时释放,避免数据库连接泄漏。 - 批量循环处理数据时建议开启数据库事务包裹全部写入逻辑,避免部分行执行成功、部分行失败导致的数据不一致问题。
内容的提问来源于stack exchange,提问作者Anosh Younas
相关产品推荐
相关产品推荐

