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

嵌套SQL查询无法获取数据:Node.js数据库查询问题求助

错误原因排查与修复方案

核心错误点

  • 查询结果处理错误:connection.query返回的rowss是多条记录组成的数组,不是单个对象,直接访问rowss.jobsID会得到undefined,导致第二个查询的fk_job = ?条件等价于fk_job = undefined,自然查不到匹配数据。
  • SQL注入风险:第一个查询直接拼接company_id到SQL语句中,存在严重的SQL注入漏洞,同时可能因参数类型不匹配导致查询异常。
  • 逻辑逻辑偏差:原代码试图用单个(不存在的)jobsID查询班次,但实际需要查询该公司所有jobs对应的班次,而非单条jobs的关联数据。

修复后的代码示例

const getCompanyShifts = (req, res) => {
  try {
    const { company_id } = req.params;
    // 用参数化查询避免注入,仅获取所需的jobsID字段
    connection.query(
      `SELECT jobsID FROM jobs WHERE company_fk = ?`,
      [company_id],
      (err, jobs) => {
        if (err) {
          return res.status(404).json({
            success: false,
            message: "未找到公司关联的岗位!",
            err
          });
        }
        if (jobs.length === 0) {
          return res.status(404).json({
            success: false,
            message: "未找到公司关联的岗位!"
          });
        }
        // 提取所有岗位ID,用IN查询匹配所有关联的已预约班次
        const jobIds = jobs.map(job => job.jobsID);
        connection.query(
          `SELECT shiftID, startTime, endTime, date, isBooked, fk_job, fk_guard 
           FROM shift 
           WHERE isBooked = 1 AND fk_job IN (?)`,
          [jobIds],
          (err, rows) => {
            if (err) {
              return res.status(500).json({
                success: false,
                message: "获取班次数据失败!",
                err
              });
            }
            if (rows.length === 0) {
              return res.status(404).json({
                success: false,
                message: "未找到公司关联的已预约班次!"
              });
            }
            // 简化数据映射逻辑,直接遍历当前行而非通过索引访问
            const shifts = rows.map(row => ({
              shiftID: row.shiftID,
              shiftStartTime: row.startTime,
              shiftEndTime: row.endTime,
              shiftDate: row.date,
              isBooked: row.isBooked,
              fk_job: row.fk_job,
              fk_guard: row.fk_guard
            }));
            res.status(200).json({
              success: true,
              message: "成功获取公司已预约班次!",
              shifts
            });
          }
        );
      }
    );
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message
    });
  }
};

额外优化建议

  • 可以用JOIN语句合并两次查询,减少数据库交互次数,提升性能:
    SELECT s.shiftID, s.startTime, s.endTime, s.date, s.isBooked, s.fk_job, s.fk_guard
    FROM jobs j
    JOIN shift s ON j.jobsID = s.fk_job
    WHERE j.company_fk = ? AND s.isBooked = 1
    
  • 建议使用Promise封装的数据库操作(如mysql2/promise),避免回调地狱,代码更易维护。

内容的提问来源于stack exchange,提问作者Mushood Hanif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:15:36