JavaScript使用tedious访问MSSQL时查询结果返回滞后如何解决
问题核心原因
你遇到的现象本质是 Node.js 异步非阻塞 IO 的执行特性:tedious 的数据库连接、SQL 查询都属于异步事件驱动逻辑,你代码中最后的打印语句是同步执行的,运行时数据库连接还未建立、查询也未执行,result 还没有被赋值,所以只能拿到空值。所有异步回调(连接成功、获取查询结果、查询完成)都会在全部同步代码执行完毕后才会触发,这就是你看到所有其他逻辑跑完才输出查询结果的原因。
改造方案
将查询逻辑封装为 Promise,使用 async/await 等待查询完成后再执行后续逻辑即可解决问题,同时补充参数化查询避免 SQL 注入风险,改造后代码如下:
const { Connection, Request, TYPES } = require('tedious'); // 封装查询逻辑为Promise function queryCustNoByEmail(email, dbConfig) { return new Promise((resolve, reject) => { let result = ''; const connection = new Connection(dbConfig); // 捕获连接级错误 connection.on('error', err => reject(err)); connection.on('connect', err => { if (err) return reject(err); // 使用参数化查询,避免SQL注入 const request = new Request( 'SELECT TOP 1 CUST_NO FROM AR_CUST WHERE email_adrs_1 = @Email;', err => { if (err) reject(err) } ); // 绑定查询参数 request.addParameter('Email', TYPES.NVarChar, email); request.on('row', columns => { columns.forEach(column => { if (column.value !== null) { result += column.value + ' '; } }); }); // 查询完成后关闭连接,返回结果 request.on('requestCompleted', () => { connection.close(); resolve(result.trim()); }); connection.execSql(request); }); connection.connect(); }); } // 调用示例 async function generateReport(email, dbConfig) { try { // 等待查询完成后再执行后续逻辑 const custNo = await queryCustNoByEmail(email, dbConfig); console.log(`returning ${custNo} for ${email}`); // 后续生成报表的逻辑写在此处即可拿到完整查询结果 } catch (err) { console.error('查询出错:', err); } }
改造说明
- 用 Promise 包裹整个异步查询流程,查询成功时调用
resolve返回结果,出错时调用reject抛出异常 - 调用时使用
await关键字等待查询执行完成,再执行后续打印、报表生成逻辑,确保拿到的结果非空 - 替换了原有的字符串拼接 SQL 写法,改用 tedious 自带的参数化查询能力,避免 SQL 注入风险
内容的提问来源于stack exchange,提问作者Daniel Bidwell
相关产品推荐
相关产品推荐

