承诺不在节点js中运行T-SQL查询

时间:2018-05-22 19:22:50

标签: sql-server node.js asynchronous stored-procedures promise

我正在尝试在节点js中编写一个函数,该函数将使用mssql运行SQL查询并返回一个promise。出于某种原因,它到了行

console.log("got to the run proc functions");

但之后不会运行任何代码。对此问题的任何帮助将不胜感激。

runProc: function (params) {  
    var sql = require("mssql");
    sql.Promise = require('promise');

    return new Promise((resolve, reject) => {
    var dbConfig = {
        server:"ip",
        database: "db",
        user:"user",
        password: "pw"
    }

    console.log("got to the run proc functions");

    var keys = Object.keys(params);

    sql.connect(dbConfig).then(pool => {
            console.log("got connected");
            const request = pool.request()

            for (var i = 0; i < keys.length; i++) {

                if (keys[i].substring(0,6)=="Common") {
                    request.input(keys[i],sql.Bit,params[keys[i]]);
                    console.log("set the bit parameters");
                }
                else {
                    request.input(keys[i],params[keys[i]]);
                    console.log("set the other parameters");
                }
            } 

            request.execute("storedprocedure")
            return request;
        }).then(result => {
                resolve(result)
        }).catch(err => {
                reject(Error(err))
        });

        sql.close();
    });
}

1 个答案:

答案 0 :(得分:0)

查看您拨打sql.close()的位置。即它在request=pool.request等之前被调用!所以,这将失败一个开始。

此外,您将返回request(这不是承诺)而不是request.execute()(这是一个承诺),因此承诺将在execute完成之前解决

最后,不需要在Promise构造函数中包含一个promise(不是这会破坏你的代码,但是不需要它)

鉴于这一切,您的代码是

runProc: function (params) {  
    var sql = require("mssql");
    sql.Promise = require('promise');

    // removed new Promise constructor as sql.connect already returns a promise we can chain to and return
    var dbConfig = {
        server:"ip",
        database: "db",
        user:"user",
        password: "pw"
    }

    console.log("got to the run proc functions");

    var keys = Object.keys(params);

    return sql.connect(dbConfig)
    .then(pool => {
        console.log("got connected");
        const request = pool.request()

        for (var i = 0; i < keys.length; i++) {

            if (keys[i].substring(0,6)=="Common") {
                request.input(keys[i],sql.Bit,params[keys[i]]);
                console.log("set the bit parameters");
            }
            else {
                request.input(keys[i],params[keys[i]]);
                console.log("set the other parameters");
            }
        } 
        // need to return the result of execute, not the request object
        return request.execute("storedprocedure")
    })
    .catch(err => throw new Error(err))
    // use Promise#finally - available in all good promise libraries
    .finally(sql.close); // sql.close AFTER we're done with it, not before
}

使用闪亮的新async / await承诺糖可以简化代码

runProc: async function (params) {  
    var sql = require("mssql");
    sql.Promise = require('promise');

    var dbConfig = {
        server:"ip",
        database: "db",
        user:"user",
        password: "pw"
    }

    console.log("got to the run proc functions");

    var keys = Object.keys(params);
    try {
        const pool = await sql.connect(dbConfig);
        const request = pool.request();
        for (var i = 0; i < keys.length; i++) {

            if (keys[i].substring(0,6)=="Common") {
                request.input(keys[i],sql.Bit,params[keys[i]]);
                console.log("set the bit parameters");
            }
            else {
                request.input(keys[i],params[keys[i]]);
                console.log("set the other parameters");
            }
        } 
        // need to return the result of execute, not the request object
        return await request.execute("storedprocedure");
    } catch (err) {
        throw new Error(err);
    } finally {
        sql.close();
    }
}