给定一个表:
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;
任何帮助都是非常感谢的。
3条答案
按热度按时间ergxz8rk1#
这是不可能的。如果你想得到三个值,你必须执行三个INSERT语句。
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中:在正常情况下,当你不混合提供和预期生成的密钥时,或者如
AUTOINCREMENT
模式文档所述:只要您从不使用最大ROWID值,并且从不删除表中具有最大ROWID的条目,上述普通ROWID选择算法将生成单调递增的唯一ROWID。
上述工作应如预期。
此Python script可用于测试多线程和多进程设置的上述正确性。
其他数据库
例如,MySQL InnoDB(至少在默认的
innodb_autoinc_lock_mode = 1
“连续”锁模式下)以类似的方式工作(尽管显然在并发条件下),并保证插入的PK可以从lastrowid
中推断出来:“简单插入”(要插入的行数是预先知道的)通过在互斥锁(一种轻量级锁)的控制下获得所需数量的自动递增值来避免表级AUTO-INC锁,该互斥锁仅在分配过程期间保持,而不是直到语句完成
2eafrhcq3#
使用RETURNING子句。此子句自版本3.35.0(2021-03-12)起可用。
对于您的示例:
有关详细信息,请参阅此文档链接:https://www.sqlite.org/lang_returning.html