当我意识到 SQLite 处理外键关系的方式与我想象的不同时,我确实花费了近三天的调试时间:
我的数据模型发生了变化,将一个表(例如 A)拆分为两个表(例如 A1 和 A)。 因此,我将 A 重命名为 A_tmp,创建了新的 A 和 A1,然后从 A_tmp 中的数据填充 A 和 A1。 当一切完成并验证后,我删除了表A_tmp。
不幸的是,其他表中引用
A作为父级的
PRAGMA foreign_keys = ON
行被删除,即使新的 A 具有所需的所有 ID(键)。
(我在其他一些表的定义中有一个REFERENCES A(ID) ON DELETE CASCADE
)
所以我想知道:SQLite 不是通过 name 引用表吗? 这将是我为什么删除其他表行的唯一解释。
表重命名后,所有引用都指向新名称:
PRAGMA FOREIGN_KEYS = ON;
CREATE TABLE a (id INTEGER PRIMARY KEY, str TEXT);
CREATE TABLE b (id INTEGER, aid INTEGER, FOREIGN KEY(aid) REFERENCES a(id) ON DELETE CASCADE);
INSERT INTO a VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
INSERT INTO b VALUES (11, 1), (12, 2), (13, 3), (14, 4);
ALTER TABLE a RENAME TO a_tmp;
.d b
输出:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE b (id INTEGER, aid INTEGER, FOREIGN KEY(aid) REFERENCES "a_tmp"(id) ON DELETE CASCADE);
INSERT INTO b VALUES(11,1); -- ~~~~~
INSERT INTO b VALUES(12,2);
INSERT INTO b VALUES(13,3);
INSERT INTO b VALUES(14,4);
COMMIT;