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

