【问题标题】:Piping mssql results to Express response管道 mssql 结果到 Express 响应
【发布时间】:2020-09-17 22:24:30
【问题描述】:

我在 NodeJS 中使用mssql 来获取大量行。

我想将结果通过管道传输到 Express 中的 HTTP 响应,但我不知道如何实现。

db.js

const sql = require('mssql');

const config = {
  user: 'user',
  password: 'pass',
  server: 'host',
  database: 'db',
};

index.js

我能够将结果流式传输到命令行:

router.get('/', function (req, res, next) {
  new sql.ConnectionPool(config).connect().then(pool => {
    const request = new sql.Request(pool);
    request.stream = true;
    request.query(`SELECT col1, col2 FROM mytable`);

    request.on('row', row => {
      console.log(row);
    });

  });
});

module.exports = router;

但是,使用 request.pipe() 会导致错误:

router.get('/', function (req, res, next) {
  new sql.ConnectionPool(config).connect().then(pool => {

    const request = new sql.Request(pool);
    request.pipe(res);
    request.query(`SELECT col1, col2 FROM mytable`);

    request.on('finish', () => {
      res.end();
    });

  });
});

_http_outgoing.js:647 抛出新的错误。TypeError('ERR_INVALID_ARG_TYPE', '第一个参数', ^

TypeError [ERR_INVALID_ARG_TYPE]:第一个参数必须是 输入字符串或缓冲区 在 write_ (_http_outgoing.js:647:11) 在 ServerResponse.write (_http_outgoing.js:622:10) 在 Request.emit (events.js:180:13

【问题讨论】:

  • 您正在使用两个请求,一个是对 sql 的请求,另一个是可能是 http req 对象。您可以将结果流式传输到控制台,因为请求对象会检查“行”事件,而您期望同一对象而不是“请求”对象上的“完成”事件。
  • 更正我上面的评论:你在同一个对象上调用 'pipe' 方法而不是 'req' 对象

标签: sql-server node.js express


【解决方案1】:

编辑:如果您关心流式传输,为什么不将其存储在对象中

router.get('/', function (req, res, next) {
  new sql.ConnectionPool(config).connect().then(pool => {
    const request = new sql.Request(pool);
    request.stream = true;
    request.query(`SELECT col1, col2 FROM mytable`);
    var output = [];
    request.on('row', row => {
      console.log(row);
      output.push(row)
    });

     request.on('finish', () => {
       res.send(output);
     });
  });
});

【讨论】:

  • 这会起作用,但是流式传输的重点是使用缓冲区并避免将整个数据集存储在内存中。这就是为什么我想通过管道获取响应。
  • 这与存储在对象中有何不同。内存仍然被使用。
  • 它会被使用,但不是一次全部使用 - 缓冲区将具有固定大小,用于流式传输更大的数据集。
【解决方案2】:
app.get("/", (req, res) => {
    new sql.ConnectionPool(config).connect().then(pool => {
    const request = new sql.Request(pool);
    request.stream = true;
    request.query('select * from tableName');
    request.on("row", async (row) => {
        if (
            !res.write(JSON.stringify(row), (err) => {
                if (err) {
                    console.error("Failed to send data");                   
                }
            })
        ) {
            request.pause();
            await new Promise((resolve) => res.once("drain", resolve));
            request.resume();
        }
    });
    request.on("error", (err) => {
        res.status(500).send({ message: err });
        res.end();
    });
    request.on("done", (result) => {
        res.end();
        console.log("Data sending complete");
    });
});
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 2019-07-25
    • 2020-02-16
    相关资源
    最近更新 更多