我有一个 sqlite3 嵌套查询案例。希望将每个查询结果推送到 json 数组并将其返回。 但第二次 select 调用时总是收到“错误:SQLITE_MISUSE:数据库句柄已关闭”。 似乎 db.close() 在第二个查询之前被调用。
这是为什么,我认为序列化可以解决这个问题。请问如何解决?
var getMyDbInfo = function(callback) {
var db = new sqlite3.Database("MyDB.sqlite3");
db.serialize(function() {
var myJsonObj = {};
db.each("select * from Table1",
function(err, row) {
console.log("\n---- 0 ----\n");
// calculate doorId from row
doorId = ...
db.all("select * from Table2 where ID=" + doorId,
function(err, row2) {
console.log("---- 6 ----\n");
if(err) {
console.log("-- ERR: " + err);
} else {
console.log(row2);
var myJsonElem = {ID:row.ID,
DoorName: row2.DoorName,
TimeSpec: row2.TimeSpec };
myJsonObj.data.push(myJsonElem);
}
}
);
}
);
callback(null, myJsonObj);
});
console.log("---- 10 ----\n");
db.close();
};
最佳答案
db.all()
调用嵌套在 db.each()
的回调函数中。 Per the docs , db.serialize()
仅序列化直接在 db.serialize()
中进行的调用回调函数。至db.serialize()
就而言,只要回调db.each()
,它的工作就完成了。被调用,因为不再需要进行内联调用,因此 db.close()
已执行。
这里有一个解决方案 - 摆脱 db.serialize()
因为您只调用 db.each()
在其中,并使用第二个“completion ”回调函数 db.each()
调用 db.close()
之后db.each()
已遍历所有行。
如果需要在 db.each()
之后进行更多数据库调用,添加db.serialize()
在 db.each()
内完成回调并从那里继续。
var getMyDbInfo = function(callback) {
var db = new sqlite3.Database("MyDB.sqlite3");
var myJsonObj = {};
db.each("select * from Table1",
function(err, row) {
console.log("\n---- 0 ----\n");
// calculate doorId from row
doorId = ...
db.all("select * from Table2 where ID=" + doorId,
function(err, row2) {
console.log("---- 6 ----\n");
if(err) {
console.log("-- ERR: " + err);
} else {
console.log(row2);
var myJsonElem = {ID:row.ID,
DoorName: row2.DoorName,
TimeSpec: row2.TimeSpec };
myJsonObj.data.push(myJsonElem);
}
}
);
},
function (err, rows) {
callback(null, myJsonObj);
db.close();
console.log("---- 10 ----\n");
}
);
};
关于node.js - sqlite3 db.close() 在 db.serialized() 完成之前调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40432228/