【问题标题】:How to get last_insert_rowid from transaction?如何从事务中获取 last_insert_rowid?
【发布时间】:2016-09-30 00:10:56
【问题描述】:

我正在尝试使用 node-sqlite3 从我的 node.js 应用程序在数据库中执行 INSERT + UPDATE 事务。但是,我无法弄清楚事务完成后如何获取 last_insert_rowid。我的查询看起来像这样:

BEGIN TRANSACTION;
    INSERT INTO <table> (field1, ...) VALUES (value1, ...);
    UPDATE <table> SET prev=last_insert_rowid() WHERE <condition>;
END TRANSACTION;

这个字符串(减去额外的空格)分配给 var q

我在某个时候使用这个打开了我的数据库:

var db = new sqlite3.Database(dbfile)

但如果我尝试使用:

db.run(q, function(err) {
    if (err) ...
    console.log(this.lastId)
})

它不仅没有错误地打印“0”,而且不会对数据库进行任何更改!!!如果我使用exec 而不是run,则查询运行成功,但我无法从 exec 中获取任何数据。

我也试过这样的:

db.exec(q, function(err) {
    if (err) ...
    db.run(";", function(err) {
        if (err) ...
        console.log(this.lastId)
    })
})

但是“run”上的“this”上下文没有lastId属性!

我也查看了 sqlite3-transaction 包,但它似乎也没有在事务回调中提供任何信息!

我不能将插入作为单独的 run() 运行,获取 this.lastId 然后使用它来运行更新,因为这会使数据库在两个语句之间处于无效状态(因此需要交易)。

如何从该事务中获取 last_insert_rowid()?

【问题讨论】:

  • 只是想知道,但在 MySQL 中,获取最近插入的 ID 的能力取决于正在使用的驱动程序(例如 Perl + DBI + DBD::mysql 模块)以及一些先决条件正在满足,例如表 ID 必须是设置为自动增量的 Integer PK。您是否检查过类似/不同的要求是否适用于您的特定情况?它还可能取决于最后运行的查询,因此可能需要检查是否可以在实际事务的上下文中执行此操作。
  • 您可以单独调用run 并仍然使用事务。只需致电run("BEGIN TRANSACTION", ...) 等,并确保在完成后致电COMMIT TRANSACTION - 或ROLLBACK TRANSACTION,如果您有错误。
  • @cartant 谢谢,我确实在昨天离开之前发现并成功尝试了这一点,但还没有时间记录它。

标签: node.js node-sqlite3


【解决方案1】:

为了获得 last_insert_rowid() ,有必要将事务分解成如下部分。首先,运行查询以开始事务:

db.run("BEGIN TRANSACTION")

接下来,运行命令插入行,在回调中获取rowid:

// replace stuff in angle brackets and ellipses with proper values
db.run("INSERT INTO <table> (field1, ...) VALUES (value1, ...);", function(err,data) {
    if (err) ...
    rowid=this.lastID // rowid declared in scope visible outside callback
})

接下来,运行更新。由于交易尚未提交,这些回调都不会被调用。

db.run("UPDATE <table> SET prev=last_insert_rowid() WHERE <condition>;", function(err,data) {
    // do whatever needs doing after update is done here
})

现在提交事务:

db.run("END TRANSACTION;")

在这种情况下,由于更新是事务中的最后一条语句,如果它成功了整个事务应该成功,所以在那个地方做任何需要做的事情应该是安全的。

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多