假设我有一个包含两个表Persons
和PhoneNumbers
的数据库,其中PhoneNumbers
表具有Persons
的外键。如果我想在一个事务中插入一个带有电话号码的人,我可以写一个这样的查询:
BEGIN TRANSACTION;
INSERT INTO Persons(Name) VALUES(...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) VALUES(last_insert_rowid(), ...);
END TRANSACTION;
但是如果我想插入一个有多个电话号码的人怎么办?显而易见的方式:
BEGIN TRANSACTION;
INSERT INTO Persons(Name) VALUES(...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) VALUES(last_insert_rowid(), ...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) VALUES(last_insert_rowid(), ...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) VALUES(last_insert_rowid(), ...);
END TRANSACTION;
当然,不起作用,因为对于第二个电话号码,last_insert_rowid()
将返回第一个电话号码的rowid而不是该人。
有没有办法使用基本SQL(特别是SQLite)?
结论
显然,没有直接的方法可以做到这一点。我已经根据@Michal Powaga的建议和一些基于临时表的其他想法做了一些基准测试,最快的方法似乎就是这样:
CREATE TEMPORARY TABLE IF NOT EXISTS Insert_PhoneNumbers(PersonForeignKey INTEGER, PhoneNumber VARCHAR);
DELETE FROM Insert_PhoneNumbers;
INSERT INTO Insert_PhoneNumbers(PhoneNumber) VALUES ('Phone 1');
INSERT INTO Insert_PhoneNumbers(PhoneNumber) VALUES ('Phone 2');
INSERT INTO Persons(Name) VALUES(...);
UPDATE Insert_PhoneNumbers SET PersonForeignKey=last_insert_rowid();
INSERT INTO PhoneNumbers(PersonForeignKey, Number)
SELECT PersonForeignKey, PhoneNumber
FROM Insert_PhoneNumbers
创建和更新临时表似乎非常快(与Persons或PhoneNumbers表上的查询相比)并且插入速度将不依赖于数据库中已有的人员/电话号码,因此这是我选择的解决方案
答案 0 :(得分:3)
您可以在人员插入临时表后存储last_insert_rowid(),否则这也可能有效:
BEGIN TRANSACTION;
INSERT INTO Persons(Name) VALUES(...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number)
VALUES(last_insert_rowid(), 'number 1');
INSERT INTO PhoneNumbers(PersonForeignKey, Number)
SELECT PersonForeignKey, 'number 2'
FROM PhoneNumbers where PhonePrimaryKey = last_insert_rowid();
INSERT INTO PhoneNumbers(PersonForeignKey, Number)
SELECT PersonForeignKey, 'number 3'
FROM PhoneNumbers where PhonePrimaryKey = last_insert_rowid();
END TRANSACTION;
答案 1 :(得分:0)
这样的事情可能有用,虽然它远非理想:
BEGIN TRANSACTION;
INSERT INTO Persons(Name) VALUES(...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) VALUES(last_insert_rowid(), ...);
INSERT INTO PhoneNumbers(PersonForeignKey, Number) SELECT PersonForeignKey, 123 WHERE PhoneNumberRowId = last_insert_rowid()
INSERT INTO PhoneNumbers(PersonForeignKey, Number) SELECT PersonForeignKey, 456 WHERE PhoneNumberRowId = last_insert_rowid()
END TRANSACTION;
并不精彩,但基本上你是链接最后一行ID来获取原始主键。