NodeJS SQL Server tedious TypeError: columns.forEach is not a function

NodeJS SQL Server tedious TypeError: columns.forEach is not a function

我正在尝试使用基于一些示例的乏味驱动程序来处理来自 SQL 服务器的结果集,但总是得到 "TypeError: columns.forEach is not a function" 错误,我无法弄清楚为什么不是为我工作。

所有模块都是最近从 npm (2018.09.21) 安装的。繁琐版本:tedious@2.6.4

示例来源: https://docs.microsoft.com/en-us/sql/connect/node-js/step-3-proof-of-concept-connecting-to-sql-using-node-js?view=sql-server-2017

https://sqlchoice.azurewebsites.net/en-us/sql-server/developer-get-started/node/sles/step/2.html

我的代码:

var express = require('express');
var router  = express.Router();
var auth = require(__dirname +'/../lib/' + 'authorization');

const config = {
  server : 'servername',
  domain : 'MYDOMAIN',
  userName : 'MYUSER',
  password : 'MYPASSWORD',
  options : {
    rowCollectionOnRequestCompletion : true,
    database : 'MYDB',
    encrypt : true,
    connectionTimeout : 1000,
    requestTimeout : 0,
    useColumnNames : true,
    isolationLevel : 'READ_UNCOMITTED',
    appName : 'My nodejs app',
    connectionRetryInterval : 5000
  },
};

var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
require('tedious').ISOLATION_LEVEL;

var connection;

router.post('/', auth.auth, async(req, res, next) => {
  try {
    connection = new Connection(config);
    connection.on('connect', function(err) {
      if (err)
      {
        console.log(new Date().toUTCString() + ' : Database connection failed to database : ' + config.options.database);
      }
      else
      {
          console.log(new Date().toUTCString() + ' : Database connected : ' + this.config.server + '.' + this.config.options.database + ' Status : ' + this.state.name);
          getList(res);
      }
    })
    .on('infoMessage', infoError)
    .on('errorMessage', infoError)
    .on('end', end)
    .on('debug', debug)
    .on('error', error)
    .on('databaseChange', databaseChange)
  }
  catch  (ex)
  {
    console.log(new Date().toUTCString() + ' : ' + 'Error: ' + ex.message);
    res.status(500);
    res.send(ex.message);
  }
});

function getList(res){
  var query = "SELECT * FROM sysfiles;";

  var request = new Request(query, function (err, rowCount, rows)
  {
    if (err)
    {
      console.log(new Date().toUTCString() + ' : ' + 'Error: ' + err);
      res.write('{ "error" : "' + err + '" }');
      res.end();
    }
    else
    {
      // console.log(rowCount + ' rows');
      var rowarray = [];
      rows.forEach(function(columns)
      {
        var rowdata = new Object();
        columns.forEach(function(column)
        {
          rowdata[column.metadata.colName] = column.value;
        });
        rowarray.push(rowdata);
      })

      res.contentType('application/json');
      retval = JSON.stringify(rowarray);
      //if (cb)
      //{
      //  retval = cb + '(' + retval + ');'
      //}
      res.write(retval);
      res.end();
    }
  // request.on('columnMetadata', columnMetadata);
  });

  request.on('done', requestDone);
  // request.addParameter('Pattern', TYPES.VarChar, '%' + pattern +'%');
  // request.addParameter('TOP', TYPES.Null, null);

  connection.execSql(request);
  // connection.callProcedure(request);
}

module.exports = router;

我得到的错误信息:

C:\mypath\myapp\routes\route1.js:60

        columns.forEach(function(column)

                ^

TypeError: columns.forEach is not a function
    at C:\mypath\myapp\routes\route1.js:60:17
    at Array.forEach (<anonymous>)
    at Request.userCallback (C:\mypath\myapp\routes\route1.js:57:12)
    at Request._this.callback (C:\mypath\myapp\node_modules\tedious\lib\request.js:60:27)
    at Connection.endOfMessageMarkerReceived (C:\mypath\myapp\node_modules\tedious\lib\connection.js:1922:20)
    at Connection.dispatchEvent (C:\mypath\myapp\node_modules\tedious\lib\connection.js:1004:38)
    at Parser.<anonymous> (C:\mypath\myapp\node_modules\tedious\lib\connection.js:805:18)
    at Parser.emit (events.js:182:13)
    at Parser.<anonymous> (C:\mypath\myapp\node_modules\tedious\lib\token\token-stream-parser.js:54:15)
    at Parser.emit (events.js:182:13)
Waiting for the debugger to disconnect

更新

正如 "Matt Kuhn" 和 "Think - Twice" 所指出的,问题出在列的类型上。感谢他们!

问题是 config.options 部分中的 "useColumnNames : true"。删除它解决了这个问题。我们可以使用 then "useColumnNames : true" 但我们需要按名称引用列而不是遍历数组。

您的代码不会调用 tedious 公开的 request.on 事件。您还可以通过调用 typeof 来测试以确保列是一个数组。您的错误意味着列不是数组,实际上可能未定义。

这是他们网站上最小示例的代码:

function executeStatement() {
  request = new Request("SELECT * FROM sysfiles", function(err, rowCount) {
    if (err) {
      console.log(err);
    } else {
      console.log(rowCount + ' rows');
    }

    connection.close();
  });

  request.on('row', function(columns) {
    console.log("columns", columns);  //should show your array
    console.log("typeof columns", typeof columns); //should by array
    columns.forEach(function(column) {
      if (column.value === null) {
        console.log('NULL');
      } else {
        console.log(column.value);
      }
    });
  });

  request.on('done', function(rowCount, more) {
    console.log(rowCount + ' rows returned');
  });

  // In SQL Server 2000 you may need: connection.execSqlBatch(request);
  connection.execSql(request);
}

在执行 forEach

之前,您需要检查列是数组还是未定义
  rows.forEach(function(columns)
  {
    var rowdata = new Object();
    if(columns){
       columns.forEach(function(column)
        {
           rowdata[column.metadata.colName] = column.value;
        });
    }
    rowarray.push(rowdata);
  });