给出一张表:
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;
非常感谢任何帮助。
答案 0 :(得分:2)
需要EXCLUSIVE锁才能写入数据库文件。文件上仅允许一个EXCLUSIVE锁,并且不允许任何其他类型的锁与EXCLUSIVE锁共存。为了最大化并发性,SQLite致力于最小化持有EXCLUSIVE锁的时间。
Last Insert Rowid的工作方式:
...将最近成功执行INSERT的rowid返回到数据库连接D上的rowid表或虚拟表中。
应该安全地假设,当编写器将其批处理INSERT
执行到ROWID表时,没有其他编写器可以使生成的主键不再是必需的。因此,插入主键为[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
“连续”锁定模式下)以类似的方式工作(尽管显然在更多并发条件下),并保证可以从{{1}推断出插入的PK。 }:
“简单插入”(预先知道要插入的行数)可以通过在互斥锁(浅色的控制)下获取所需的自动递增值数量来避免表级AUTO-INC锁定。权重锁定)仅在分配过程中才保持有效,直到语句完成为止
答案 1 :(得分:1)
这是不可能的。如果要获得三个值,则必须执行三个INSERT语句。