2017-12-12 16 views
1

私はリレーショナルDBをリレーショナルDBにしようとしています。だから私は一意のIDのないデータから始めています。Node.js連鎖はMySQLのループで約束します

これらの行を介して1つのSQL呼び出しループから結果を取得する必要があり、それぞれについて、最初の結果の一部を使用してSQL SELECTを実行し、次に次の結果を使用して別のSQLを選択し、最初と最後のクエリから。

私はNode.jsを使用しており、ES6はすべてを順番に保つことを約束していますが、何か不足しているようです。私は実際に余分なSQL呼び出しを行い、その結果を3番目のクエリで使用しようとしていましたが、もう1つの呼び出しを別の呼び出しに渡すだけで単純化しています。

多分、いくつかのコードは私が何をしようとしているのかを示す助けになるでしょう。ここで

は約束を返す私のクエリクラスです:

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です:今コンソールで、私は続く有効な組織オブジェクトは、取得します。 2番目のクエリの前に割り当てられているcontactIdを取得するにはどうすればよいですか。私はこの非同期のことを正しくやっていないことを知っています。

答えて

0

私はこれを行う方法を見つけましたが、それはちょっとチーズです。 contactIdをSQLクエリに定数として含めて組織を取得しました。その値を.thenに渡してすべてを整理しておくことができました。

マイSQL2文は次のようになります。そして、

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

たときにそのクエリが返す、私はちょうど私がからorganizationIdを取得し、同じ結果から、結果として[0] .contactIdを正しいcontactIdを引き出すことができます。

ここ

は最終的なコードである:

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 } 

そして、私は1つcontact_organizationから返されたすべての連絡先の行のために挿入しまっ最初のクエリ。

0

このようなものを試してみてください。ただの簡単な解決策。 (未検証)。

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(); 
    }); 
+0

私はそれをきれいにしなければなりませんでした。例えば、結果[i]はselectOrgの約束ではなくforループの中にあるべきです。その時点で必要なのは「結果」だけです。しかし、私はまだすべての組織が同じcontactId(17848)にリンクしています。これは最後のcontactIdです。 – ScottM

+0

あなたのコードは悪くはありませんでした。私はそれをかなり速く走らせることができました。しかし、それは上記の元のコードと同じ結果を生成します。 – ScottM

+0

@ScottM質問を正しく読まなかった。私は「2番目のクエリの前に割り当てられているcontactIdを取得するにはどうすればよいですか」と理解していません。 – Muthukumar

関連する問題