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

NodeJS+MySQL心愿单删除异常:非NULL条件下无数据受影响

心愿单删除API查询异常问题

我用Node.js实现心愿单删除API时遇到了问题:当colorID和storageID都为NULL时,删除能正常执行并移除数据;但只要其中一个不为NULL,删除查询就返回0 rows affected。

问题代码

router.delete("/", (req, res) => {
  const { userID, prodID, colorID, storageID } = req.body;
  const sql = `
    DELETE FROM wishlist 
    WHERE prodID = ? 
      AND userID = ? 
      AND (colorID = ? OR (colorID IS NULL AND ? IS NULL))
      AND (storageID = ? OR (storageID IS NULL AND ? IS NULL));
  `;

  db.query(
    sql,
    [prodID, userID, colorID, colorID, storageID, storageID],
    (err, result) => {
      if (err) {
        console.error("Error deleting from wishlist:", err);
        res.status(500).send("Internal Server Error");
      } else {
        console.log(`Deleted ${result.affectedRows} record(s).`);
        res.send(result);
      }
    }
  );
});

问题原因

核心问题出在SQL的条件逻辑上:

  • MySQL中用普通=运算符比较NULL时,结果永远是FALSE,哪怕两边都是NULL。
  • 原条件逻辑搞反了判断顺序,应该根据传入参数值匹配数据库字段,而非反过来。当传入参数非NULL时,原条件里的(colorID IS NULL AND ? IS NULL)直接失效,只剩colorID = ?,若参数类型与数据库字段不匹配(比如传字符串、数据库存整数),就会导致匹配失败。

解决方案

方案1:使用MySQL NULL-safe等于运算符(推荐)

<=>是MySQL专门处理NULL比较的运算符:两边都是NULL时返回TRUE,两边非NULL且值相等时也返回TRUE,直接简化条件:

router.delete("/", (req, res) => {
  const { userID, prodID, colorID, storageID } = req.body;
  const sql = `
    DELETE FROM wishlist 
    WHERE prodID = ? 
      AND userID = ? 
      AND colorID <=> ?
      AND storageID <=> ?;
  `;

  db.query(
    sql,
    [prodID, userID, colorID, storageID],
    (err, result) => {
      if (err) {
        console.error("Error deleting from wishlist:", err);
        res.status(500).send("Internal Server Error");
      } else {
        console.log(`Deleted ${result.affectedRows} record(s).`);
        res.send(result);
      }
    }
  );
});

方案2:修正原逻辑的条件判断

如果不想用<=>,可以调整条件顺序,先判断传入参数是否为NULL,再匹配数据库字段:

router.delete("/", (req, res) => {
  const { userID, prodID, colorID, storageID } = req.body;
  const sql = `
    DELETE FROM wishlist 
    WHERE prodID = ? 
      AND userID = ? 
      AND (? IS NULL AND colorID IS NULL OR colorID = ?)
      AND (? IS NULL AND storageID IS NULL OR storageID = ?);
  `;

  db.query(
    sql,
    [prodID, userID, colorID, colorID, storageID, storageID],
    (err, result) => {
      if (err) {
        console.error("Error deleting from wishlist:", err);
        res.status(500).send("Internal Server Error");
      } else {
        console.log(`Deleted ${result.affectedRows} record(s).`);
        res.send(result);
      }
    }
  );
});

这个逻辑是:如果传入参数是NULL,匹配数据库对应字段为NULL;如果传入参数有值,匹配数据库字段等于该值,完全覆盖业务场景。

内容的提问来源于stack exchange,提问作者Quang Link

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:55:39