Node.js在与MySQL的循环中链接承诺

时间:2017-12-12 20:14:01

标签: mysql node.js loops promise

我正在尝试将非关系数据库转换为关系数据库。所以我从没有唯一ID的数据开始。

我需要通过这些行从一个SQL调用循环中获取结果,并且对于每个行,使用第一个结果的一部分执行SQL SELECT,然后使用下一个结果执行另一个SQL选择,然后使用来自第一个和最后一个查询。

我正在使用Node.js和ES6承诺保持一切顺序,但我似乎错过了一些东西。我实际上是在尝试进行额外的SQL调用,并在第三个查询中使用该结果,但我将其简化为只调用一个调用以反馈给另一个调用。

也许某些代码可以帮助显示我想要做的事情。

这是我的返回promises的查询类:

var mysql = require('mysql');

class Database {
    constructor() {
        this.connection = mysql.createConnection({
            host: "localhost",
            user: "root",
            password: "root",
            database: "pressfile"
        }); 
    }

    query(sql, args) {
        return new Promise((resolve, reject) => {
            this.connection.query(sql, args, (err, result, fields) => {
                if (err) return reject(err);

                resolve (result);
            });
        });
    }

    close() {
        return new Promise((resolve, reject) => {
            this.connection.end(err => {
                if (err) return reject (err);

                resolve();
            });
        });
    }
}

这很多都是从教程网站上偷来的,这部分看起来效果很好。然后是循环,以及多个查询:

var contactId;
var address1;
var orgName;

var database = new Database();

database.query("SELECT * FROM contact")
    .then( result => {
        for (var i = 0; i < result.length; i++) {
            contactId = result[i].contactId;
            orgName = result[i].org;

            var sql2 = "SELECT * FROM organization WHERE (name = \"" + orgName + "\")";
            console.log(sql2);

            database.query(sql2)
            .then(result2 => {
                console.log(result2);

                var orgId = result2[0].organizationId;
                var sql3 = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")";
                console.log(sql3);

                return ""; //database.query(sql3);
            }).then( result3 => {
                console.log(result3);
            });
        }
    }).catch((err) => {
        console.log(err);
        databse.close();
    });

我知道它最终会解开,但我不想做INSERT查询,直到我知道我能做对。现在在控制台中,我获得了一个有效的组织对象,后跟:

`INSERT INTO contact_organization (contactId, organizationId) VALUES (17848, 29)'

17848是for循环中返回的最后一个contactId。如何获取在第二个查询之前分配的contactId。我知道我没有正确地做这个异步的东西。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情。只是一个快速解决方案(未经测试)。

const selectOrg = (result) => {
  contactId = result[i].contactId;
  orgName = result[i].org;
  var sql = "SELECT * FROM organization WHERE (name = \"" + orgName + "\")";

  return database.query(sql);
};

const insertOrg = (result) => {
  var orgId = result[0].organizationId;
  var sql = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")";
  return database.query(sql);
};

database.query("SELECT * FROM contact")
  .then(result => {
    const promises = [];
    for (var i = 0; i < result.length; i++) {
      promises << selectOrg(result)
        .then(insertOrg);
    }
    return Promise.all(promises);
  })
  .then(allResults => {
    console.log(allResults);
  })
  .catch((err) => {
    databse.close();
  });

答案 1 :(得分:0)

我找到了一种方法来做到这一点,但它有点俗气。我将contactId作为常量包含在SQL查询中以获取组织,因此我可以将值传递给.then,保持一切顺序。

我的sql2语句变为:

var sql2 = "SELECT *, " + contactId + " AS contactId FROM organization WHERE (name = \"" + orgName + "\")";

然后当该查询返回时,我可以从结果[0] .contactId中拉出正确的contactId,从我获得organizationId的相同结果中。

以下是最终代码:

database.query("SELECT * FROM contact")
    .then( result => {
        for (var i = 0; i < result.length; i++) {
            var contactId = result[i].contactId;
            var orgName = result[i].org;

            var sql2 = "SELECT *, " + contactId + " AS contactId FROM organization WHERE (name = \"" + orgName + "\")";

            database.query(sql2)
            .then(result2 => {
                var orgId = result2[0].organizationId;
                var contactId = result2[0].contactId;

                var sql3 = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")";
                console.log(sql3);

                return database.query(sql3);
            }).then( result3 => {
                console.log(result3);
            });
        }
    }).catch((err) => {
        console.log(err);
        databse.close();
    });

console.log(result3)返回一堆这些:

OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '',
  protocol41: true,
  changedRows: 0 }

我为第一个查询返回的每个联系人行插入了一个contact_organization。