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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:42:49