尝试顺序执行未知数量的查询的节点/ mssql /异步

时间:2018-06-29 10:32:29

标签: sql-server node.js asynchronous transactions

我正在使用带有mssql和async软件包的node.js v10.4.1。我试图按承诺顺序执行多个查询,但是,有一点我需要执行一组查询,直到运行时才知道确切数量。我试图为此使用async.mapSeries。请参见下面的代码。请注意,查询被包装在事务中,因为要么所有插入都必须成功,要么所有插入都必须失败(即回滚)。

const theTransaction = thePool.transaction();
theTransaction.begin(err => {
    if (err) {
        //handle err here
    };
    console.log("Begin write issue transaction...");
    theTransaction.request()
        .input("myInputParameter", sql.NVarChar, myInputParameter)
        .query("insert into ... values ...")
        .then(result => {
                    console.log(result);
                    var theList = getInsertedList(); // returns array of string 
                    async.mapSeries(theList, async (item, next) => {
                       console.log(item);
                       theTransaction.request()
                          .input("parameter", sql.NVarChar, item)
                          .query("insert into ... values ...")
                          .then(next);
                    });
             }) // error handling left out for brevity
       .then(result => {
                   console.log("Committing...");
                   theTransaction.commit(); // error handling left out
                   console.log("Committed.");
             })
       .catch(err => {
                   console.log("Aborting...");
                   theTransaction.rollback(); // error handling left out
                   console.log("Transaction rolled back.");
             });
    });

(在将代码移植到此注释中时,可能会出现语法错误,但是我的原始代码可以编译并很好地加载。)

运行此命令时,出现错误:

RequestError: Requests can only be made in the LoggedIn state, not the SentClientRequest state
我解释为

表示mapSeries中的后续查询不等待先前的查询完成。从mapSeries列表中进行第一次查询后,就会发生错误。

任何有关如何解决此问题的想法将不胜感激。

我当时在想我可能必须从句法上以字符串形式从List中构建一个查询,然后只在.then中执行一个查询。这种方法的问题在于,在这种情况下,我需要直接在查询字符串中包含参数,而不是使用.input(这不理想,因为它可能会引发SQL注入攻击)。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以将查询作为地图传递。然后,它将不取决于您传递的查询数。

const request = new sql.Request();
for (key in inputMap) {
  request.input(key, inputMap[key]);
}