You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击提交后数据库库存更新异常:输入数量致负库存问题排查

问题原因及修复方案

核心问题

库存变成负数的直接原因是没有正确获取对应商品的当前库存值:

  • 代码里执行了查询product_stock表的语句,但完全没从查询结果中取出数据赋值给$row变量
  • 未初始化的$row['qty_stock']会被视为空值,计算$stock = $row['qty_stock'] - $qty时,相当于0 - 输入数量,最终得到负数

修复步骤

1. 正确获取对应商品的库存数据

不要查询整个库存表,只查询当前操作商品的库存,同时取出结果赋值:

// 替换原查询语句,仅查询当前商品的库存
$stock_query = mysqli_query($link, "SELECT qty_stock FROM product_stock WHERE product_name='$product'");
// 取出查询结果到$row变量
$row = mysqli_fetch_assoc($stock_query);
// 检查是否查询到商品,避免无数据时报错
if($row) {
    $stock = $row['qty_stock'] - $qty;
    $update_que = "UPDATE product_stock SET qty_stock='$stock' WHERE product_name='$product'";
    $run_update = mysqli_query($link,$update_que);
}

2. 修复SQL注入漏洞(关键优化)

你的代码直接将POST参数拼入SQL语句,存在严重的安全风险,必须用mysqli预处理语句重构:

// 插入采购记录的预处理示例
$insert_stmt = mysqli_prepare($link, "INSERT INTO purchasedproducts (invoice_id, productname, quantity, amtpaid) VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($insert_stmt, "isii", $invoice, $product, $qty, $amtpaid);
mysqli_stmt_execute($insert_stmt);

// 查询库存的预处理示例
$stock_stmt = mysqli_prepare($link, "SELECT qty_stock FROM product_stock WHERE product_name=?");
mysqli_stmt_bind_param($stock_stmt, "s", $product);
mysqli_stmt_execute($stock_stmt);
mysqli_stmt_bind_result($stock_stmt, $current_stock);
mysqli_stmt_fetch($stock_stmt);

// 更新库存的预处理示例
if(isset($current_stock)) {
    $new_stock = $current_stock - $qty;
    $update_stmt = mysqli_prepare($link, "UPDATE product_stock SET qty_stock=? WHERE product_name=?");
    mysqli_stmt_bind_param($update_stmt, "is", $new_stock, $product);
    mysqli_stmt_execute($update_stmt);
}

3. 增加错误排查逻辑

可以添加SQL执行错误提示,方便排查问题:

if(!$run_update) {
    echo "库存更新失败: " . mysqli_error($link);
    exit;
}

完整修复后的代码示例

<?php
include 'config.php';
$invoice = $_POST['invoiceid'];
if(isset($_POST['submit'])){
    $checked_array=$_POST['prod'];
    
    foreach ($_POST['prodname'] as $key => $value) {
        if(in_array($_POST['prodname'][$key], $checked_array)){
            $product=$_POST['prodname'][$key];
            $price= $_POST['price'][$key];
            $qty= $_POST['qty'][$key];
            
            $amtpaid = $price * $qty;

            // 插入采购记录(预处理防注入)
            $insert_stmt = mysqli_prepare($link, "INSERT INTO purchasedproducts (invoice_id, productname, quantity, amtpaid) VALUES (?, ?, ?, ?)");
            mysqli_stmt_bind_param($insert_stmt, "isii", $invoice, $product, $qty, $amtpaid);
            mysqli_stmt_execute($insert_stmt);

            // 查询当前商品库存
            $stock_stmt = mysqli_prepare($link, "SELECT qty_stock FROM product_stock WHERE product_name=?");
            mysqli_stmt_bind_param($stock_stmt, "s", $product);
            mysqli_stmt_execute($stock_stmt);
            mysqli_stmt_bind_result($stock_stmt, $current_stock);
            mysqli_stmt_fetch($stock_stmt);

            // 更新库存(仅当查询到库存时执行)
            if(isset($current_stock)) {
                $new_stock = $current_stock - $qty;
                $update_stmt = mysqli_prepare($link, "UPDATE product_stock SET qty_stock=? WHERE product_name=?");
                mysqli_stmt_bind_param($update_stmt, "is", $new_stock, $product);
                mysqli_stmt_execute($update_stmt);
            } else {
                echo "未找到商品「$product」的库存记录";
            }
        }        
    }
}
header('Location: sample.php');
?>

内容的提问来源于stack exchange,提问作者Lyka C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:45:28