如何在SQLite中返回多行插入的id?

wb1gzix0  于 2023-03-23  发布在  SQLite
关注(0)|答案(3)|浏览(205)

给定一个表:

CREATE TABLE Foo(
    Id INTEGER PRIMARY KEY AUTOINCREMENT,
    Name TEXT
);

如何返回同时插入的多行的id:

INSERT INTO Foo (Name) VALUES
('A'),
('B'),
('C');

我知道last_insert_rowid(),但我没有找到任何将其用于多行的示例。
我试图实现的目标可以在这个 SQL Server 示例中看到:

DECLARE @InsertedRows AS TABLE (Id BIGINT);
INSERT INTO [Foo] (Name) OUTPUT Inserted.Id INTO @InsertedRows VALUES 
    ('A'),
    ('B'),
    ('C');
SELECT Id FROM @InsertedRows;

任何帮助都是非常感谢的。

ergxz8rk

ergxz8rk1#

这是不可能的。如果你想得到三个值,你必须执行三个INSERT语句。

jei2mxaa

jei2mxaa2#

给定SQLite3 locking
写入数据库文件需要一个EXCLUSIVE锁。文件上只允许有一个EXCLUSIVE锁,并且不允许任何类型的其他锁与EXCLUSIVE锁共存。为了最大化并发性,SQLite会尽量减少持有EXCLUSIVE锁的时间。
Last Insert Rowid是如何工作的:
...返回最近成功INSERT到数据库连接D上的rowid表或虚拟表的rowid。
可以安全地假设,当一个writer对ROWID表执行其批处理INSERT时,不可能有其他writer使生成的主键成为非后件。因此,插入主键是[lastrowid - rowcount + 1, lastrowid]。或者在Python SQLite3 API中:

cursor.execute(...)  # multi-VALUE INSERT
assert cursor.rowcount == len(values)
lastrowids = range(cursor.lastrowid - cursor.rowcount + 1, cursor.lastrowid + 1)

在正常情况下,当你不混合提供和预期生成的密钥时,或者如AUTOINCREMENT模式文档所述:
只要您从不使用最大ROWID值,并且从不删除表中具有最大ROWID的条目,上述普通ROWID选择算法将生成单调递增的唯一ROWID。
上述工作应如预期。
Python script可用于测试多线程和多进程设置的上述正确性。

其他数据库

例如,MySQL InnoDB(至少在默认的innodb_autoinc_lock_mode = 1“连续”锁模式下)以类似的方式工作(尽管显然在并发条件下),并保证插入的PK可以从lastrowid中推断出来:
“简单插入”(要插入的行数是预先知道的)通过在互斥锁(一种轻量级锁)的控制下获得所需数量的自动递增值来避免表级AUTO-INC锁,该互斥锁仅在分配过程期间保持,而不是直到语句完成

2eafrhcq

2eafrhcq3#

使用RETURNING子句。此子句自版本3.35.0(2021-03-12)起可用。
对于您的示例:

INSERT INTO "Foo" ("Name") VALUES
('A'),
('B'),
('C')
RETURNING "Id";

有关详细信息,请参阅此文档链接:https://www.sqlite.org/lang_returning.html

相关问题