node.js循环数据库插入

时间:2018-10-28 17:25:03

标签: javascript mysql node.js promise

我有一个带有地址对象的应用程序,以及与该应用程序关联的人员列表。

{
  field1: value,
  field2: value,
  address: {
    street: value,
    apt: value,
    city: value
  },
  owners: [
    {name: value, etc.},
    {name: value, etc.}
  ]
}

我将所有者传递给一个遍历所有者的函数,并将每个查询的信息传递给异步函数:

async function insertAllOwners(appId, owners) {
  for (var i = 0, len = owners.length; i < len; i++) {
    console.log("insert owner", i);
    await insertOwner(appId, owners[i]);
  }
}

此处被调用的函数将查询变成一个承诺:

function insertOwner(appId, owner)  {
  let sqlOwner = 'insert into ...';
  return new Promise( ( resolve, reject ) => {
    mySqlClient.query(sqlOwner, [appId, owner.memberType ...], (err, rows) => {
      if ( err )
        return reject( err );
      console.log("rows:", rows);
      resolve( rows );
    } );
  } );
}

地址插入物嵌套在应用程序插入物中,然后将调用所有者插入循环的代码嵌套在地址插入物中。循环所有者插入函数在这里调用:

      if(app.owners) {
        /* insert owners, then commit.  else, just commit.*/
        insertAllOwners(appId, app.owners).then( result => {
          mySqlClient.commit(function(err, result) {
            if (err) { 
              console.error("ERROR DURING COMMIT:", err);
              mySqlClient.rollback(function() {
                throw err;
              });
            }
            else {
              console.log("commit:",result);
            }
          });                  
        });
      }

输出看起来很完美,但实际上并没有提交任何内容(新行未显示)。有什么建议么?日志输出如下:

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

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

insert owner 0
rows:
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 70,
  serverStatus: 1,
  warningCount: 0,
  message: '',
  protocol41: true,
  changedRows: 0
}

...

insert owner 4
rows:
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 74,
  serverStatus: 1,
  warningCount: 0,
  message: '',
  protocol41: true,
  changedRows: 0
}

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

1 个答案:

答案 0 :(得分:1)

第一件事是,这不是执行查询的好习惯。

您正在做什么,以运行一个for循环,每个循环执行每个查询。通过这种方式,您可以将负载分配给mysql。而且执行您的API将花费更长的时间。

我建议这样。

在for循环中:

for (var i = 0, len = owners.length; i < len; i++) {
   inserData.push(owners[i]); // Add all data in to array ... 
}

此后,执行查询一次,并包含所有数据。

connection.query("INSERT INTO TABLE (columns) VLAUES ? " , insertData)...