C#库存不足校验异常:下单量超库存仍显示成功且库存变负
问题分析与修复方案
核心问题
- 判断逻辑完全失效:你用
updateQuery == null作为分支条件,但updateQuery是主动拼接的字符串,永远不可能为null,导致代码永远执行成功提示分支,完全忽略库存校验。 - 未做库存校验:代码没有先查询商品当前库存,根本无法判断下单量是否超过库存,直接扣减导致库存变为负数。
- SQL注入风险:直接将用户输入的文本拼接进SQL语句,存在被恶意攻击的风险。
修复后的代码
try { // 校验输入是否为有效数字 if (!int.TryParse(TextBox_qtys.Text, out int orderQty) || !int.TryParse(TextBox_id.Text, out int prodId)) { MessageBox.Show("请输入有效的数字", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 查询当前商品库存 string checkStockQuery = "SELECT ProdQty FROM Product WHERE ProdId = @ProdId"; SqlCommand checkCmd = new SqlCommand(checkStockQuery, dBCon.GetCon()); checkCmd.Parameters.AddWithValue("@ProdId", prodId); dBCon.OpenCon(); object stockResult = checkCmd.ExecuteScalar(); if (stockResult == DBNull.Value || stockResult == null) { MessageBox.Show("商品不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); dBCon.CloseCon(); return; } int currentStock = Convert.ToInt32(stockResult); // 确定提示信息 string tipMessage = orderQty > currentStock ? "Low in Stock" : "Order Added Successfully"; MessageBoxIcon tipIcon = orderQty > currentStock ? MessageBoxIcon.Warning : MessageBoxIcon.Information; // 执行库存扣减(参数化查询避免注入) string updateQuery = "UPDATE Product SET ProdQty = ProdQty - @OrderQty WHERE ProdId = @ProdId"; SqlCommand updateCmd = new SqlCommand(updateQuery, dBCon.GetCon()); updateCmd.Parameters.AddWithValue("@OrderQty", orderQty); updateCmd.Parameters.AddWithValue("@ProdId", prodId); updateCmd.ExecuteNonQuery(); // 更新界面并提示 MessageBox.Show(tipMessage, "提示", MessageBoxButtons.OK, tipIcon); getTable(); clear(); } catch (Exception ex) { MessageBox.Show($"操作失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { // 确保数据库连接关闭 if (dBCon.GetCon().State == System.Data.ConnectionState.Open) { dBCon.CloseCon(); } }
修复说明
- 新增库存校验流程:先查询商品当前库存,再和下单量对比,根据结果显示对应提示。
- 输入合法性校验:用
int.TryParse过滤非数字输入,避免程序崩溃。 - 参数化SQL:替换字符串拼接为参数化查询,彻底解决SQL注入问题。
- 异常与连接管理:通过
try-catch-finally捕获异常,确保数据库连接无论操作成功与否都会关闭。
内容的提问来源于stack exchange,提问作者Saeed Bama
相关产品推荐
相关产品推荐

