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

Node.js使用mssql存储过程流式返回多数据集路由返回问题

在Hapi路由中流式处理mssql多数据集存储过程返回值

看起来你已经在独立函数里跑通了流式获取多数据集的逻辑,现在要把这套逻辑整合到Hapi的路由handler里对吧?我来帮你梳理下完整的实现方案,解决变量冲突和结果返回的问题。

首先先修正你代码里的一个小坑:你把新建的sql.Request实例命名成了request,这和路由handler自带的request参数重名了,会覆盖掉原有的请求对象,必须先改个名字,比如sqlRequest。

接下来是完整的handler实现,我会把流式处理多数据集的逻辑补全,加上错误处理和最终的结果返回:

handler: async function(request, reply) {
  try {
    const inputValues = request.payload.inputParams;
    const procName = request.params.procedureName;
    
    // 修正变量名冲突:将sql.Request实例命名为sqlRequest,避免覆盖路由的request参数
    const sqlRequest = new sql.Request(mainsettings.connection);
    sqlRequest.stream = true;

    // 存储所有数据集的数组
    const recordSetArr = [];
    // 当前正在处理的数据集容器
    let currentRecordSet = [];

    // 监听新数据集开始事件:每次存储过程返回新数据集时触发
    sqlRequest.on('recordset', (columns) => {
      currentRecordSet = [];
      recordSetArr.push(currentRecordSet);
    });

    // 监听单行数据返回事件:逐行接收数据并加入当前数据集
    sqlRequest.on('row', (row) => {
      currentRecordSet.push(row);
    });

    // 监听单个数据集处理完成事件:可在此做单数据集的统计或额外处理
    sqlRequest.on('done', (result) => {
      console.log(`当前数据集处理完成,共${result.rowsAffected[0]}行数据`);
    });

    // 用Promise包裹流式逻辑,确保所有数据处理完成后再返回结果
    await new Promise((resolve, reject) => {
      // 监听数据库请求错误
      sqlRequest.on('error', (err) => {
        console.error('数据库请求出错:', err);
        reject(err);
      });

      // 监听整个存储过程执行完成事件:所有数据集都处理完毕
      sqlRequest.on('doneProc', () => {
        resolve();
      });

      // 传入存储过程参数
      for (const key in inputValues) {
        if (inputValues.hasOwnProperty(key)) {
          sqlRequest.input(key, inputValues[key]);
        }
      }
      // 执行存储过程
      sqlRequest.execute(procName);
    });

    // 所有数据集处理完成后,返回结果给客户端
    reply(recordSetArr);
  } catch (err) {
    // 捕获所有异常,返回500错误码和错误信息
    reply.response({ error: err.message }).code(500);
  }
}

关键细节说明:

  • 变量名冲突修复:将sql.Request实例重命名为sqlRequest,避免覆盖路由自带的request参数
  • 流式事件分工:
    • recordset:标记新数据集的开始,初始化对应的数据容器
    • row:逐行接收数据,存入当前数据集容器
    • done:单个数据集处理完成的回调,可做单数据集的统计或自定义处理
    • doneProc:整个存储过程执行完毕的回调,触发结果返回逻辑
  • 异步逻辑封装:用Promise包裹流式处理流程,确保所有数据处理完成后再返回响应,符合Hapi handler的异步要求
  • 错误兜底:同时监听数据库请求错误和用try-catch捕获全局异常,确保所有错误都能被捕获并返回给客户端

如果你的存储过程返回的不同数据集需要差异化处理(比如第一个是列表数据,第二个是统计汇总),可以在recordset事件里通过columns参数判断当前数据集的字段结构,再做针对性的处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:34:22