仅当变量为True时更新数据库及多If语句跳转异常求助
解决库存扣减逻辑跳过判断的问题
我猜你大概率是把多个独立的验证条件用else if连在一起了,导致前两个条件满足后,后面的库存检查直接被跳过,最终执行了更新操作导致库存负数。咱们一步步来解决这个问题:
问题核心原因
如果你的代码结构是类似下面这样的else if链式判断,那问题就很明显了:
// 错误示例:用else if连接独立的验证步骤 if (requestQty <= 0) { ... } else if (con.State == ConnectionState.Closed) { con.Open(); } else if (requestQty > availableStock) { ... } // 前两个条件满足的话,这里永远不会执行 else if (canUpdate) { ... } // 直接跳到这里执行更新
else if是互斥分支,只要前面任意一个条件成立,后面的分支就会被直接跳过。而我们的库存检查、更新权限判断都是独立的必要验证,不能用互斥分支来写。
修正后的完整逻辑代码
我结合你的代码片段,整理了正确的逻辑,加上了必要的细节处理:
protected void Button1_Click(object sender, EventArgs e) { // 第一步:先做输入合法性校验,避免格式错误 if (!int.TryParse(TextBox1.Text, out int requestQty) || requestQty <= 0) { Response.Write("<script>alert('请输入有效的请求数量(大于0的整数)');</script>"); return; } string cs = System.Configuration.ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString; // 使用using语句自动释放数据库连接,避免资源泄漏 using (SqlConnection con = new SqlConnection(cs)) { try { con.Open(); // 第二步:读取当前最新的可用库存(必须在验证前读取,确保数据是最新的) int availableStock = 0; // 替换为你实际的产品ID获取方式,比如从DropDownList或隐藏域取 string getStockSql = "SELECT Stock FROM Products WHERE ProductId = @ProductId"; using (SqlCommand getStockCmd = new SqlCommand(getStockSql, con)) { getStockCmd.Parameters.AddWithValue("@ProductId", 1); // 示例产品ID,按需修改 object stockResult = getStockCmd.ExecuteScalar(); if (stockResult != null && int.TryParse(stockResult.ToString(), out availableStock)) { // 第三步:检查请求数量是否超出库存,不满足直接终止 if (requestQty > availableStock) { Response.Write("<script>alert('请求数量超出可用库存,无法操作');</script>"); return; } // 第四步:仅当控制变量为True时,执行数据库更新 bool canUpdate = true; // 替换为你实际的变量判断逻辑 if (canUpdate) { string updateSql = "UPDATE Products SET Stock = Stock - @Qty WHERE ProductId = @ProductId"; using (SqlCommand updateCmd = new SqlCommand(updateSql, con)) { updateCmd.Parameters.AddWithValue("@Qty", requestQty); updateCmd.Parameters.AddWithValue("@ProductId", 1); // 对应上面的产品ID int affectedRows = updateCmd.ExecuteNonQuery(); if (affectedRows > 0) { Response.Write("<script>alert('库存更新成功');</script>"); } else { Response.Write("<script>alert('更新失败,未找到对应产品');</script>"); } } } else { Response.Write("<script>alert('当前不允许执行库存更新操作');</script>"); } } else { Response.Write("<script>alert('获取库存信息失败,请检查产品状态');</script>"); } } } catch (Exception ex) { // 生产环境建议记录日志,不要直接暴露错误信息给用户 Response.Write($"<script>alert('操作出错:{ex.Message}');</script>"); } } }
关键修正点说明
- 拆分独立验证步骤:每个条件判断都是独立的
if,验证不通过时用return终止后续逻辑,确保所有必要检查都能被执行到 - 使用
using管理资源:自动释放数据库连接和命令对象,避免资源泄漏 - 先读最新库存:确保库存数据是实时的,避免并发操作导致的库存不一致问题
- 参数化SQL:防止SQL注入攻击,同时避免格式错误
- 完善异常处理:捕获操作中的异常,给用户友好提示(生产环境记得记录日志)
内容的提问来源于stack exchange,提问作者carol
相关产品推荐
相关产品推荐

