我有一个带有
INTEGER PRIMARY KEY
的表和指向其他表的几个 FOREIGN KEY
字段:
CREATE TABLE DifficultTable
(
id INTEGER NOT NULL UNIQUE,
name TEXT,
fooId INTEGER,
barId INTEGER,
PRIMARY KEY(id AUTOINCREMENT),
FOREIGN KEY(fooId) REFERENCES FooTable(id)
FOREIGN KEY(barId) REFERENCES BarTable(id)
);
CREATE TABLE FooTable
(
id INTEGER NOT NULL UNIQUE,
name TEXT NOT NULL UNIQUE,
PRIMARY KEY (id AUTOINCREMENT)
);
CREATE TABLE BarTable
(
id INTEGER NOT NULL UNIQUE,
name TEXT NOT NULL UNIQUE,
PRIMARY KEY (id AUTOINCREMENT)
);
为了简化访问它的 C-API,我还在
VIEW
中提供此数据,将这些外键解析为名称,并为 INSERT
提供触发器:
CREATE VIEW SimpleView
AS
SELECT
DifficultTable.id,
DifficultTable.name,
FooTable.name AS foo,
BarTable.name AS bar
FROM
DifficultTable
LEFT JOIN
FooTable ON DifficultTable.fooId = FooTable.id
LEFT JOIN
BarTable ON DifficultTable.barId = BarTable.id;
CREATE TRIGGER SimpleInsert
AS
INSTEAD OF INSERT ON SimpleView
BEGIN
INSERT INTO DifficultTable(name, fooId, barId)
VALUES (NEW.name,
(SELECT id FROM FooTable WHERE name = New.foo),
(SELECT id FROM BarTable WHERE name = New.bar)
);
END;
如果我在
FooTable
和 BarTable
中插入一些值,我可以确认 sqlite3_last_insert_rowid()
运行良好:
sqlite> INSERT INTO FooTable(name) VALUES ("One"),("Two"),("Three"),("Four");
sqlite> SELECT last_insert_rowid();
4 <-- Good. There are now four rows in FooTable.
sqlite> INSERT INTO BarTable(name) VALUES ("One"),("Two");
sqlite> SELECT last_insert_rowid();
2 <-- Good. There are now two rows in BarTable
但是如果我插入
SimpleView
,last_insert_rowid()
不会更新:
sqlite> INSERT INTO SimpleView (name, foo, bar) VALUES ("One", "Four", "Two");
sqlite> SELECT last_insert_rowid();
2 <-- Expected 1 because there is now 1 row in DifficultTable
有没有简单的方法来获取 rowid?
运行这些命令后数据库中所有数据的摘要:
FooTable
id | 名字 |
---|---|
1 | 一个 |
2 | 两个 |
3 | 三 |
4 | 四个 |
吧台
id | 名字 |
---|---|
1 | 一个 |
2 | 两个 |
简单视图
id | 名字 | 富 | 酒吧 |
---|---|---|---|
1 | 一个 | 四个 | 两个 |
难看
id | 名字 | fooId | 栏ID |
---|---|---|---|
1 | 一个 | 4 | 2 |
sqlite3_last_insert_rowid()
,因为它只是 C 中的 1-liner。我也许可以执行另一个 SQL 查询,但是否保证 id
始终会递增(即使行被删除?)
SELECT id
FROM DifficultTable
ORDER BY id DESC
LIMIT 1
这是根据肖恩的评论给出的答案。 最后插入 Rowid 文档 说:
如果在触发器内发生 INSERT,则只要触发器正在运行,此例程就会返回插入行的 rowid。一旦触发器程序结束,该例程返回的值将恢复为触发触发器之前的值。
这意味着在触发器上完成 INSERT 后您无法使用
sqlite3_last_insert_rowid()
。另一种方法是执行查询:
SELECT id
FROM DifficultTable
ORDER BY id DESC
LIMIT 1
AUTOINCREMENT
: 的描述而填满了表格
通常的算法是为新创建的行指定一个比插入之前表中最大 ROWID 大 1 的 ROWID。 ...如果最大的 ROWID 等于最大可能的整数...数据库引擎开始随机挑选正候选 ROWID,直到找到以前未使用过的 ROWID。
AUTOINCREMENT
没有必要。使用此关键字将上面的描述更改为:
为新行选择的 ROWID 至少比同一表中之前存在的最大 ROWID 大 1