我知道在sqlite3
中提供了多个关于多次插入的解决方案,但我正在寻找有效的方法,其中数据被插入到两个表中,而第二个表的数据依赖于第一个表。这是一个node js
应用程序。
我在sqlite3中有两个表programs
和tests
。表tests
包含programs
的ID,即一个程序可以包含多个测试。
sqlite3
模块的官方页面上建议的方法如下:
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run("CREATE TABLE lorem (info TEXT)");
var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
stmt.run("Ipsum " + i);
}
stmt.finalize();
db.each("SELECT rowid AS id, info FROM lorem", function(err, row) {
console.log(row.id + ": " + row.info);
});
});
db.close();
在我的要求中,我必须在两个表中插入数据,所以我使用以下代码:
var programData = resp.program_info; // contains complete data of programs and tests
db1.run("INSERT INTO programs (`parent_prog_id`, `prog_name`, `prog_exercises`, `prog_orgid`, `prog_createdby`, `prog_created`, `prog_modified`, `prog_status`) VALUES (?,?,?,?,?,?,?,?)",prog.parent_program_id,prog.programName, JSON.stringify(prog), req.session.org_id, prog.created_by, prog.created_at, prog.updated_at, prog.program_status,function(err){
if(err){
throw err;
}else{
var count = 1;
var step2PostedData = prog;
for (i in step2PostedData.testsInfo) {
var c = 0;
for(j in step2PostedData.testsInfo[i]){
var obj = Object.keys(step2PostedData.testsInfo[i])[c];
db1.prepare("INSERT INTO `tests` ( `parent_name`,`test_name`, `test_alias`, `sequences`, `duration`, `prog_id`, `org_id`, `test_createdby`, `test_created`, `test_modified`, `test_status`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")
.run(count, obj,
step2PostedData.testsInfo[i][j].alias,
step2PostedData.testsInfo[i][j].sequences,
step2PostedData.testsInfo[i][j].duration,
this.lastID, // using this I am getting program id
req.session.org_id,
prog.created_by,
prog.created_at,
prog.updated_at,
prog.program_status);
c++;
count++;
}
}
现在,我的查询是如果我使用建议的方法,那么我没有从programs
表格中获取最后一个插入的程序ID。没有回调。
e.g。如果我使用以下代码;
var stmt = db1.prepare("INSERT INTO programs (`parent_prog_id`, `prog_name`, `prog_exercises`, `prog_orgid`, `prog_createdby`, `prog_created`, `prog_modified`, `prog_status`) VALUES (?,?,?,?,?,?,?,?)";
var stmt2 = db1.prepare("INSERT INTO `tests` ( `parent_name`,`test_name`, `test_alias`, `sequences`, `duration`, `prog_id`, `org_id`, `test_createdby`, `test_created`, `test_modified`, `test_status`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")
programData.forEach(function(prog){
// Inserts data in programs table
stmt.run(prog.parent_program_id,prog.programName, JSON.stringify(prog), req.session.org_id, prog.created_by, prog.created_at, prog.updated_at, prog.program_status);
for (i in step2PostedData.testsInfo) {
var c = 0;
for(j in step2PostedData.testsInfo[i]){
var obj = Object.keys(step2PostedData.testsInfo[i])[c];
stmt2.run(
count,
obj,
step2PostedData.testsInfo[i][j].alias,
step2PostedData.testsInfo[i][j].sequences,
step2PostedData.testsInfo[i][j].duration,
'what should be there',// How to get last program inserted ID there
req.session.org_id,
prog.created_by,
prog.created_at,
prog.updated_at,
prog.program_status);
} // inner for loop ends
} // outer for loop ends
stmt.finalize();
stmt2.finalize();
});
如果我使用返回null的this.lastID
,显然没有回调
现在
如果我使用sqlite3_last_insert_rowid()
那么
sqlite3_last_insert_rowid未定义错误。
如果我使用last_insert_rowid()
,则不使用last_insert_rowid()
定义
查询:
如何在那里插入最后插入的程序ID,目前我的最后一个程序ID为null?
修改
当且仅当使用回调是获取最后一个ID的方式或方法时,我将保持我的代码正在运行。任何人都可以建议我如何提高插入速度。
谢谢!
答案 0 :(得分:1)
sqlite3_last_insert_rowid()是C API的一部分。 last_insert_rowid()是一个SQL函数。
如果documentation告诉您lastID
在回调中有效,那么您必须使用回调。
只需将所有子INSERT移动到父INSERT的完成回调中。
(建议的代码不是为了展示如何获取最后插入的ID;它只是演示了实际插入的值。)