嵌套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
相关产品推荐
相关产品推荐

