Sqlite3读取表中的所有记录并返回



我试图读取sqlite3表中的所有记录并通过回调返回它们。但似乎尽管使用序列化,这些调用仍然是异步的。下面是我的代码:

var readRecordsFromMediaTable = function(callback){
    var db = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
    var allRecords = [];
    db.serialize(function() {
        db.each("SELECT * FROM MediaTable", function(err, row) {
            myLib.generateLog(levelDebug, util.inspect(row));
            allRecords.push(row);
        }
        callback(allRecords);
        db.close();
    });
}

当回调被触发时,数组打印'[]'。

是否有另一个调用,我可以做(而不是db.each),将给我所有的行在一个镜头。我不需要遍历每一行。

如果没有,我如何读取所有记录,然后调用回调结果?

我找到了这个问题的答案。这里是给任何正在寻找的人:

var sqlite3 = require("sqlite3").verbose();
var readRecordsFromMediaTable = function(callback){
    var db = new sqlite3.Database(file, sqlite3.OPEN_READONLY);
    db.serialize(function() {
        db.all("SELECT * FROM MediaTable", function(err, allRows) {
            if(err != null){
                console.log(err);
                callback(err);
            }
            console.log(util.inspect(allRows));
            callback(allRows);
            db.close();
        });

    });
}

基于承诺的方法

var readRecordsFromMediaTable = function(){
  return new Promise(function (resolve, reject) {
    var responseObj;
    db.all("SELECT * FROM MediaTable", null, function cb(err, rows) {
      if (err) {
        responseObj = {
          'error': err
        };
        reject(responseObj);
      } else {
        responseObj = {
          statement: this,
          rows: rows
        };
        resolve(responseObj);
      }
      db.close();
    });
  });
}

使用db。所有的回调都是正确的,因为db。每个都不是真正需要的。但是,如果db。解决方案在node-sqlite3 API文档中提供,https://github.com/mapbox/node-sqlite3/wiki/API#databaseeachsql-param--callback-complete:

Database#each(sql, [param,…], [callback], [complete])

在调用了所有的行回调之后,如果存在,将调用完成回调。第一个参数是一个错误对象,第二个参数是检索的行数

所以,在结束第一个回调的地方,不是}put},而是function(){…}。像这样:

var readRecordsFromMediaTable = function(callback){
var db = new sqlite3.Database(file, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
var allRecords = [];
    db.serialize(function() {
        db.each("SELECT * FROM MediaTable", function(err, row) {
            myLib.generateLog(levelDebug, util.inspect(row));
            allRecords.push(row);
        }, function(err, count) {
            callback(allRecords);
            db.close();
        }
    });
}

我知道我有点晚了,但既然你在这里,请考虑一下:

注意,它首先检索所有结果行并将它们存储在内存中。对于可能有大结果集的查询,使用database# each函数来检索所有行,或者使用database# prepare,然后调用多个Statement#get来检索以前未知数量的行。

node-sqlite3文档中所述,如果您需要非常大或未知的行数,则应该使用.each() ,因为.all()将在转储之前将所有结果集存储在内存中。

话虽如此,看看科林·基南的回答。

我以不同的方式处理这个问题,因为这些调用是异步的,您需要等到它们完成才能返回它们的数据。我用的是setInterval(),有点像把披萨面团扔到空中,然后等着它掉下来。

var reply = '';
db.all(query, [], function(err, rows){
    if(err != null) {
        reply = err;
    } else {
        reply = rows;
    }
});
var callbacker = setInterval(function(){
    // check that our reply has been modified yet
    if( reply !== '' ){
        // clear the interval
        clearInterval(callbacker);
        // do work
    }
}, 10); // every ten milliseconds

老问题,但我遇到的问题,用不同的方法来解决问题。Promise选项可以工作,尽管在db.all(…)调用的情况下对我来说有点太啰嗦。

我使用Node的事件概念:

var eventHandler = require('events')

在你的Sqlite函数:

function queryWhatever(eventHandler) {
    db.serialize(() => {
       db.all('SELECT * FROM myTable', (err, row) => {
            // At this point, the query is completed
            // You can emit a signal
            eventHandler.emit('done', 'The query is completed')
        })
     })
}

然后,给你的回调函数eventHandler,它会对'done'事件做出反应:

eventHandler.on('done', () => {
    // Do something
})

最新更新