【问题标题】:passing Tedious connection as parameter将繁琐的连接作为参数传递
【发布时间】:2018-09-10 21:48:45
【问题描述】:

我正在尝试使用利用 Tedious 库构建的一组简单函数来访问 Microsoft SQL Server。这是我的“工具”文件:

'use strict';
const tedious = require('tedious');
const q = require('q');

var Connection = tedious.Connection;
var Request = tedious.Request;

module.exports = {

    connectSQL : function(config) {

        var connection = new Connection(config);

        connection.on('connect', function(err) {
            if (err) {
                console.log('FAIL ON CONNECT');
                console.log(err);
            } else {
                try {
                    /* ----- */
                    return connection;
                } catch (err) {
                    console.log(err);
                    return;
                }
            }
        });

        connection.on('error', function(err) {

           if (err) {
                console.log('FAIL ON ERROR');
                console.log(err);
            } else {
                console.log("Error called with no err object.");
            }
        });

    },

    executeSQL: function(connection, requestString) {

        var results = [];

        var request = new Request( requestString , function(err, data) {
            if (err) {
                console.log(err);
            } else {
                console.log( data );
            }

        });

        request.on('row', function(row) {
            //console.log(row);
            results.push( row );

        });

        request.on('requestCompleted', function(){
            console.log('Finished');
            return results;
        });

        connection.execSql(request);
    }
}

我在我的服务器文件中按如下方式调用这些函数。

const sqlTools = require('./sqlTools.js');

var connection = sqlTools.connectSQL(config);

sqlTools.executeSQL(connection, "select * from dbo.test");

但是,我收到错误“TypeError: Cannot read property 'execSql' of undefined”,即使我在调用函数 sqlTools.executeSQL 之前让程序休眠 10 秒(显然不理想)。

我能够通过调用 sqlTools.connectSQL 函数中的请求(在“/* ----- */”处)来使其工作,但我想重新使用繁琐的连接来建立多个来电。有什么建议么?谢谢!

~~~~~~~编辑~~~~~~~~~~

在 akinjide 的帮助下,我能够实现回调,允许我对我的 SQL 数据库进行一次调用。但是,我正在努力履行后续电话的承诺。我改变了我的“工具”文件:

'use strict';
const tedious = require('tedious');
const q = require('q');

var Connection = tedious.Connection;
var Request = tedious.Request;

module.exports = {

    connectSQL: function(config) {

        var deferred = q.defer();
        var connection = new Connection(config);

        connection.on('connect', function(err) {
            if (err) {
                deferred.reject( err );
            } else { 
                deferred.resolve( connection );
            }
        });

        connection.on('error', function(err) {
            deferred.reject(err);
        });

        return deferred.promise;
    },


    executeSQL: function(connection, requestString, callback) {

        var results = [];

        const request = new Request(requestString, function(err) {

            callback(err);

        });

        request.on('row', function(row) {

            results.push(row);

        });

        request.on('requestCompleted', function() {

            console.log('request completed!');
            callback(null, results);

        });

        connection.execSql(request);
    }
}

我这样称呼这段代码......

var promise = sqlTools.connectSQL(config);

promise.then(function (connection) {
    sqlTools.executeSQL(connection, "select * from dbo.test", function(err, results) {

      if (err) {
        console.log(err);
      }

      console.log(results);

    });

}).catch(function (err) {
    console.log(err);  
}).then(function (connection) {

    sqlTools.executeSQL(connection, "select * from dbo.test2", function(err, results) {

      if (err) {
        console.log(err);
      }

      console.log(results);

    });

}).catch(function(err) {
    console.log(err);
});

这会正确返回第一次调用的结果,但不幸的是,第二次调用返回此错误“TypeError: Cannot read property 'execSql' of undefined”,因为它第二次无法识别连接。有什么建议吗?

【问题讨论】:

标签: sql node.js tedious


【解决方案1】:

更好的方法是将 node.js 回调样式函数作为参数传递给 connectSQL

return 关键字在异步程序中不起作用。

'use strict';

const tedious = require('tedious');
const Connection = tedious.Connection;
const Request = tedious.Request;

module.exports = {
    connectSQL: function(config, callback) {
        const connection = new Connection(config);

        connection.on('connect', function(err) {
            if (err) {
                callback(err);
            } else {
                callback(null, connection);
            }
        });

        connection.on('error', function (err) {
           callback(err);
        });
    },
    executeSQL: function(connection, requestString, callback) {
        let results = [];

        const request = new Request(requestString, function(err) {
            callback(err);
        });

        request.on('row', function(row) {
            results.push(row);
        });

        request.on('requestCompleted', function(){
            console.log('Finished');
            callback(null, results);
        });

        connection.execSql(request);
    }
}

然后你可以要求,使用sqlTools.connectSQL传递两个参数configfunction(err, connection) {}

const sqlTools = require('./sqlTools');

sqlTools.connectSQL(config, function(err, connection) {
   if (err) {
     console.log('FAIL ON CONNECT');
     console.log(err);
   }

   sqlTools.executeSQL(connection, "select * from dbo.test", function (err, results) {
      if (err) {
         console.log(err);
      } 

      console.log(results);
   });
});

【讨论】:

  • 感谢您的回复!这很有帮助,但我想知道如何重用连接(也许如果我正在构建一个 RESTful 应用程序)。我在网上看到了这个例子example,但它每次都会重新启动连接,我无法想象这是理想的。
  • 您可以从var promise = sqlTools.connectSQL(config); 返回一个promise,然后将promise 重用为promise.then(function (connection) { console.log(connection) })。但我知道您可以关闭连接并在需要时打开。
  • 我在原始问题中添加了一些额外的代码,我尝试实现承诺,但只取得了部分成功。如果您有任何想法,请告诉我,谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-10-29
  • 1970-01-01
  • 2011-02-11
  • 2018-01-31
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多