【问题标题】:node.js Global connection already exists. Call sql.close() firstnode.js 全局连接已经存在。先调用 sql.close()
【发布时间】:2025-12-08 20:25:01
【问题描述】:

我正在尝试使用来自 sql server 数据库的 node.js 创建 Web 服务,在前端,当我同时调用这 2 个 Web 服务时,它会引发错误全局连接已存在。先调用sql.close()。

任何解决方案?

var express = require('express');
var router = express.Router();
var sql = require("mssql");

router.get('/Plant/:server/:user/:password/:database', function(req, res, next) {

    user = req.params.user;
    password = req.params.password;
    server = req.params.server;
    database = req.params.database;


    // config for your database
    var config = {
        user: user,
        password: password,
        server: server,
        database:database

    };

    sql.connect(config, function (err) {



        // create Request object
        var request = new sql.Request();

        // query to the database and get the records
        request.query("SELECT  distinct PlantName FROM MachineryStateTable"
            , function (err, recordset) {

                if (err) console.log(err)
                else {

                    for(i=0;i<recordset.recordsets.length;i++) {
                        res.send(recordset.recordsets[i])
                    }

                }
               sql.close();

            });

    });

});





router.get('/Dep/:server/:user/:password/:database/:plantname', function(req, res, next) {

    user = req.params.user;
    password = req.params.password;
    server = req.params.server;
    database = req.params.database;
    plantname = req.params.plantname;

    // config for your database
    var config = {
        user: user,
        password: password,
        server: server,
        database:database

    };

    sql.connect(config, function (err) {



        // create Request object
        var request = new sql.Request();

        // query to the database and get the records
        request.query("SELECT  distinct DepName FROM MachineryStateTable where PlantName= '"+plantname+"'"
            , function (err, recordset) {

                if (err) console.log(err)
                else {

                    for(i=0;i<recordset.recordsets.length;i++) {
                        res.send(recordset.recordsets[i])

                    }
                    sql.close();
                }

            });
    });
});



module.exports = router;

【问题讨论】:

    标签: node.js sql-server web-services


    【解决方案1】:

    你必须创建一个poolConnection 试试这个:

    new sql.ConnectionPool(config).connect().then(pool => {
    
      return pool.request().query("SELECT * FROM MyTable")
    
      }).then(result => {
    
        let rows = result.recordset
        res.setHeader('Access-Control-Allow-Origin', '*')
        res.status(200).json(rows);
        sql.close();
    
      }).catch(err => {
    
        res.status(500).send({ message: `${err}`})
        sql.close();
    
      });
    

    【讨论】:

    • 谢谢你,为我工作得很好
    • 谢谢。好东西。我们需要关闭游泳池吗?像 pool.close() 之类的东西。是否可以一次定义池化代码并在多个地方使用?
    • 谢谢,如果我使用 ---- const db_pool = new sql.ConnectionPool(db_config);我应该调用 db_pool.close();而不是 sql.close();
    • 这太糟糕了......他们不知道连接池是什么吗?因此,您创建一个新的“ConnectionPool”并连接到它。似乎与我有联系,而不是游泳池。然后你调用'sql.close()'?您可以一次创建两个连接池吗?您是否为每个请求创建一个?
    【解决方案2】:

    documentation开始,应该在连接上使用close方法,而不是在需要的模块上,

    所以应该这样使用

    var connection = new sql.Connection({
    user: '...',
    password: '...',
    server: 'localhost',
    database: '...'
    });
    connection.close().
    

    还有一些建议,
    1. 将 res.send 置于循环中不是一个好主意,您可以回复整个记录集或对其进行操作,将结果存储在变量中并将其发送回。
    2. 尝试使用promises,而不是回调,这样会让流程更整洁

    【讨论】:

    • 应用程序的用户没有从登录页面连接到任何数据库,他应该指定IP地址和密码然后选择数据库。
    • 上面的连接对象可以提供请求中的凭据。
    • 你能举个例子说明一下吗?
    【解决方案3】:

    您必须使用 ConnectionPool。

    Next 函数返回一个包含我的查询结果的记录集。

    async function execute2(query) {
    
        return new Promise((resolve, reject) => {
    
            new sql.ConnectionPool(dbConfig).connect().then(pool => {
                return pool.request().query(query)
            }).then(result => {
    
                resolve(result.recordset);
    
                sql.close();
            }).catch(err => {
    
                reject(err)
                sql.close();
            });
        });
    
    
    }

    在我的代码中运行良好!

    【讨论】:

      【解决方案4】:

      如果这个问题仍然困扰你,那么改变核心 api。 转到 node_modules\mssql\lib\base.js 在第 1723 行,在 if 条件之前添加以下代码 globalConnection = null

      【讨论】:

        【解决方案5】:

        如果有人来这里试图找出如何使用带参数的 SQL Server 池连接:

        var executeQuery = function(res,query,parameters){
        
           new sql.ConnectionPool(sqlConfig).connect().then(pool =>{
        
            // create request object
            var request = new sql.Request(pool);
        
           // Add parameters
            parameters.forEach(function(p) {
            request.input(p.name, p.sqltype, p.value);
            });
        
            // query to the database
            request.query(query,function(err,result){
        
                    res.send(result);
                    sql.close();
        
            });
         })       
        } 
        

        【讨论】:

          【解决方案6】:

          不要阅读他们的文档,我不认为它是由实际使用该库的人编写的 :) 也不要注意事物的名称,'ConnectionPool' 似乎实际上并不是任何类型的连接池。如果您尝试从池中创建多个连接,则会收到错误消息。这是我最终得到的代码:

          const sql = require('mssql');
          
          let pool = new sql.ConnectionPool(config); // some object that lets you connect ONCE
          let cnn = await pool.connect(); // create single allowed connection on this 'pool'
          let result = await cnn.request().query(query);
          console.log('result:', result);
          cnn.close(); // close your connection
          return result;
          

          此代码可以并行运行多次,并且似乎创建了多个连接并正确关闭它们。

          【讨论】:

            最近更新 更多