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

Node.js使用Promise查询mssql时如何返回全部结果行

问题说明

基于Promise封装mssql查询的GetProducts方法,开启流模式查询Products表时仅返回第一行数据,需要修改为返回全部查询结果。

原有错误实现

return new Promise((resolve, reject) => {
    sql.connect(config, err => {
        const request = new sql.Request()
        request.stream = true
        request.query('select * from Products')
        request.on('row', row => {
            const products = [{ id: row.ProductID, name: row.ProductName}]
            resolve(products)
        })
    })
    sql.on('error', err => {
        console.log(err)
    })
})
}

调用代码

GetProducts()
    .then((products) => {
        console.log(products)
    });

当前错误返回

[ { id: 1, name: 'Chai' } ]
错误原因
  • Promise状态一旦变更就会凝固,原有代码在row事件第一次触发(读到第一行数据)时就调用了resolve,后续读取到的行不会再触发返回
  • 没有监听流读取完成的事件,无法获知所有行何时读取完毕
  • 错误捕获逻辑不全,连接、查询阶段的错误没有正确透传给Promise的reject
修复方案

流模式修复(保留流读取逻辑)

提前初始化数组缓存每一行读取到的数据,等所有行读取完成触发done事件时,再调用resolve返回完整数组,同时补全全链路错误捕获:

function GetProducts() {
    return new Promise((resolve, reject) => {
        sql.connect(config, err => {
            if (err) return reject(err);
            const request = new sql.Request();
            request.stream = true;
            const products = [];
            request.query('select * from Products');

            // 逐行读取时仅做数据缓存,不执行resolve
            request.on('row', row => {
                products.push({ id: row.ProductID, name: row.ProductName });
            });

            // 所有行读取完成后返回完整结果
            request.on('done', () => {
                resolve(products);
            });

            // 捕获查询阶段错误
            request.on('error', err => {
                reject(err);
            });
        });
        // 捕获数据库连接全局错误
        sql.on('error', err => {
            reject(err);
        });
    });
}

简化写法(无需流处理时推荐)

如果不需要逐行处理流数据,可以直接关闭流模式(mssql默认非流模式),查询回调会直接返回全量结果,代码更简洁:

function GetProducts() {
    return new Promise((resolve, reject) => {
        sql.connect(config, err => {
            if (err) return reject(err);
            const request = new sql.Request();
            request.query('select * from Products', (err, result) => {
                if (err) return reject(err);
                const products = result.recordset.map(row => ({
                    id: row.ProductID,
                    name: row.ProductName
                }));
                resolve(products);
            });
        });
        sql.on('error', reject);
    });
}

两种写法调用逻辑不变,执行后都会返回包含所有商品数据的数组。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:27:25