Node.js后端向前端传递多个数据库查询结果的实现方案——员工考勤系统工时同页展示问题
解决方法:同时传递两个数据库查询结果到EJS视图
你遇到的核心问题是两个查询分开执行,没法把结果合并后一起传给res.render。下面提供两种实用的方案,帮你把每日工时和每周总工时同时渲染到index视图中:
方案1:嵌套回调(适合简单场景)
在第一个查询的回调函数里执行第二个查询,等两个结果都拿到后,再一起传递给视图:
router.get('/', (req, res) => { const week = DateTime.now().weekNumber; // 先查询每日工时数据 conexion.query('SELECT * FROM assistance WHERE week = ?', week, (error, dailyResults) => { if(error){ console.error(error); return res.status(500).send('查询每日工时失败'); } // 拿到每日工时后,再查询每周总工时 conexion.query( 'SELECT time_format(SUM(TIMEDIFF(a.exit, a.entry)), "%H:%i") AS hours from assistance a WHERE a.week = ?', week, (totalError, totalResults) => { if(totalError){ console.error(totalError); return res.status(500).send('查询总工时失败'); } // 合并两个结果,传递给视图 res.render('index', { dailyHours: dailyResults, // 每日工时数据 totalHours: totalResults[0].hours // 总工时(注意取数组第一个元素的hours字段) }); } ); }); });
方案2:Async/Await + Promise(更优雅,避免回调地狱)
把数据库查询封装成Promise,然后用async/await并行执行两个查询,代码结构更清晰:
// 先封装查询为Promise,方便复用 const runQuery = (sql, params) => { return new Promise((resolve, reject) => { conexion.query(sql, params, (error, results) => { if (error) reject(error); else resolve(results); }); }); }; // 路由处理函数用async修饰 router.get('/', async (req, res) => { try { const week = DateTime.now().weekNumber; // 并行执行两个查询,提高效率 const [dailyResults, totalResults] = await Promise.all([ runQuery('SELECT * FROM assistance WHERE week = ?', week), runQuery('SELECT time_format(SUM(TIMEDIFF(a.exit, a.entry)), "%H:%i") AS hours from assistance a WHERE a.week = ?', week) ]); // 渲染视图,传递两个结果 res.render('index', { dailyHours: dailyResults, totalHours: totalResults[0].hours }); } catch (error) { console.error('查询出错:', error); res.status(500).send('服务器内部错误'); } });
EJS视图中的使用方式
修改你的EJS代码,分别使用dailyHours渲染每日工时表格,totalHours展示总工时:
<!-- 每日工时表格 --> <table> <thead> <tr> <th>员工姓名</th> <th>签到时间</th> <th>签退时间</th> </tr> </thead> <tbody> <% dailyHours.forEach(assistance => { %> <tr> <td><%= assistance.employee_name %></td> <!-- 替换成你实际的字段名 --> <td><%= assistance.entry %></td> <td><%= assistance.exit %></td> </tr> <% }) %> </tbody> </table> <!-- 每周总工时展示 --> <div> <div>Total hours: <%= totalHours %></div> </div>
关键注意点:
- 总工时查询返回的是一个数组(即使只有一行结果),所以要通过
totalResults[0].hours取出实际的工时值,而不是直接传递整个数组。 - 一定要做好错误处理,避免单个查询失败导致整个服务崩溃。
内容的提问来源于stack exchange,提问作者adan gimenez
相关产品推荐
相关产品推荐

