PHP开发需求:插入同发票下商品时增数量而非新增记录
解决发票下同款商品累加数量而非重复插入的方案
这问题我熟!要实现「同一发票下已有同款商品时累加数量,而非生成重复记录」,核心是靠MySQL的INSERT ... ON DUPLICATE KEY UPDATE语法,再配合联合唯一索引触发更新逻辑。具体步骤如下:
1. 给数据表添加联合唯一约束
首先得让数据库能识别「发票号+商品ID」的组合是唯一的,所以要给目标表加一个联合唯一索引。假设你的表名叫sales_products(替换成你实际的表名),执行这条SQL:
ALTER TABLE sales_products ADD UNIQUE KEY idx_invoice_product (invoice, product_id);
这样当同一发票下插入同款商品时,数据库会检测到唯一键冲突,自动触发后续的数量更新操作。
2. 修改PHP的插入逻辑
把原来的普通INSERT语句替换成带更新逻辑的版本,同时一定要用预处理语句防止SQL注入(生产环境绝对不能省!)。结合你给出的代码片段,修改后的完整代码大概是这样:
<?php session_start(); include('../connect.php'); // 先处理POST参数,加基础的空值校验 $invoice = $_POST['invoice'] ?? ''; $product_id = $_POST['product_id'] ?? ''; $qty = (int)$_POST['qty'] ?? 0; $saleproduct = $_POST['saleproduct'] ?? ''; $pt = $_POST['pt'] ?? ''; // 假设amount是商品总价,这里根据你的实际业务调整计算逻辑 $amount = (float)$_POST['amount'] ?? 0; // 使用预处理SQL,避免SQL注入 $sql = "INSERT INTO sales_products (invoice, product_id, qty, saleproduct, pt, amount) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE qty = qty + ?, -- 累加现有数量 amount = amount + ?"; -- 如果是总价也需要累加就保留,单价的话可以删掉这行 // 这里假设你的connect.php用的是PDO连接,如果是mysqli语法要对应调整 $stmt = $pdo->prepare($sql); // 绑定参数:前6个是INSERT的字段值,后2个是UPDATE要累加的数量和金额 $stmt->execute([$invoice, $product_id, $qty, $saleproduct, $pt, $amount, $qty, $amount]); // 可选:判断操作类型(插入/更新) if ($stmt->rowCount() === 1) { echo "新商品已成功添加到该发票"; } else { echo "同款商品数量已累加更新"; } ?>
几个关键注意点:
- 预处理语句必须用:直接把POST参数拼进SQL里会有严重的SQL注入风险,这是开发的基本规范。
- 金额字段的处理:如果
amount是商品单价,那更新时不需要修改它,直接删掉amount = amount + ?这行即可;如果是总价,就保留这行同步累加。 - 参数校验:我加了基础的空值处理,你可以根据业务需求补充更严格的校验(比如判断发票号、商品ID是否为空,数量是否为正整数等)。
3. 额外提示
- 如果你的数据表之前已经存在重复的「发票号+商品ID」记录,加唯一索引会失败。可以先备份数据,再执行下面的SQL清理重复项(保留每组重复记录的第一条):
DELETE t1 FROM sales_products t1 INNER JOIN sales_products t2 WHERE t1.id < t2.id AND t1.invoice = t2.invoice AND t1.product_id = t2.product_id; - 确认你的
connect.php使用的是PDO或mysqli扩展,老的mysql扩展已经被废弃,不要再用了。
内容的提问来源于stack exchange,提问作者Hassane Samir
相关产品推荐
相关产品推荐

