如何在sqlite3中实现嵌套查询

时间:2016-11-07 23:11:50

标签: node.js sqlite

所以我在node.js中有这个2层查询,每个查询都可以返回多个结果。我的代码实际上暂时忽略了这一点。这是我能得到的最好的,看起来很有效。

  1. 如何纠正它,我不知道如何回复第二个。

  2. 在第二个查询完成之前总是调用db.close(),即使我有serialize()。

    var getInfo1Db = function(callback){     var db = new sqlite3.Database(" DB.sqlite3");

    var cnt = 0; 
    var info1JsonObj = [];
    
    db.all("select * from Info1DB", 
        function(err, rows) {
    
            db.serialize(function() {
                for(var ii=0, len=rows.length; ii<len; ii++) {
    
                    var t2 = rows[ii].info1;
                    var doorId =  ...
    
                    db.all("select * from DoorDB where ObjectID=" + doorId,
                        function(err, row2) {
    
                            if(err) {
                            } else {
                                var doorName = row2[0]...
    
                                var info1JsonElem = {
                                    "DoorName" : doorName
                                };
    
                                info1JsonObj.push(info1JsonElem);
                                cnt++;
                                if(cnt === rows.length) {
                                    callback(null, info1JsonObj);
                                }
                             }
                         }
                     ); // for the only door info based on door id
    
                } // for each row of info1
    
                db.close(); // why this finishes before the 2nd db.all
            } );  // end of serialize
    
    });
    

    };

3 个答案:

答案 0 :(得分:0)

如何使用2功能来做这些?

function db_query1(your_param,...., callback){
  // database operation
   db.run( sql , [param,...] , function(err,rows){
      if(err) // return
      else{
         // get rows with callback
         callback(null, rows);
      }
   });
}

function db_query2(your_param,...., callback){
  // database operation
   db.run( sql , [param,...] , function(err,rows){
      if(err) // return
      else{
         // get rows with callback
         callback(null, rows);
      }
   });
}

并调用这些功能:

db_query1(....,function(err,result1){
   if(err) ...// return 
   // do the things with result1
   // And then call query2
   db_query2(....,function(err,result2){
      if(err) ...// return 
      // do the things with result1
   });
});

希望这会有所帮助:)

答案 1 :(得分:0)

您可以使用Promises.all,数组和节点sqlite3 db.each()的第二个回调,当所有行都已获取时执行该回调。 Node Sqlite3 db.each usage简化嵌套查询,并且

我无法真正了解您使用的变量的含义,因此我假设Info1DB中的每一行都与DoorDB字段doorId具有一对多的关系。

async function getInfo (callback) {
    sql = "select * from Info1DB;";
    numVersions = 0;
    countVersions = 0;
    info1JsonObj = [];
    db.serialize(function() {
        db.each(sql, [], (err, info1Row) => {
            sql = "select * from DoorDB where ObjectID=?;";
                info1Row.doors = [];
            doorId = ...
            db.each(sql, [doorId], (err, doorRow) => {
                info1Row.doors.push(new Promise((resolve, reject) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(doorRow);
                    }
                }));
            }, (err, num) => {
                Promise.all(info1Row.doors)
                    .then((doors) => {
                        info1Row.doors = doors;
                        info1JsonObj.push(info1Row);
                        countVersions++;
                        if (countVersions == numVersions) {
                            callback(null, info1JsonObj);
                        }
                    }).catch((err) => {
                        callback(err, null);
                    });
            });
        }, (err, versions) => {
            numVersions = versions;
        });
    });
}

答案 2 :(得分:0)

你不能用sqlite3的正常方式实现嵌套查询。 (我的意思是你甚至不能用 callback hell 的方式来做,因为 sqlite3 需要在调用另一个查询之前关闭连接。否则你总是会出错)

您必须使用 Promiseasyncawait 来执行此操作。 (花30分钟学习这3个字是值得的)

第一步。像这样定义一个异步函数:

async query_1() {
  new Promise(resolve => {

      db = ...
      db.serialize( () => {
        db.get('select .. from ... where id = 1', [], (error, row) => {
           // here is the KEY: put the result into resolve 
           // this equals to the "return" statement in non-sync method.
           resolve(row)
        }
      })
      db.close()
  })
}

并像这样实现你的 query_2 函数:

async query_2() {
  let query_1_result = await this.query_1()

  db = ...
  db.serialize( () => {
    db.get('select .. from ... where dependency_id = ' + query_1_result, [], (error, row) => {
       // other code here...
    }
  })
  db.close()
}

参考我的回答:https://stackoverflow.com/a/67881159/445908