我试图在SQLite中使用外键支持来维护具有自反连接的单表数据库的引用完整性。
。
PRAGMA foreign_keys = ON;
create table tree (
objectId text unique not null,
parentObjectID text,
foreign key (parentObjectID) references tree(parentObjectID) on delete cascade
)
我希望的行为是,当父行被删除时,它的子行和它们的子行也被删除。
但是,当我试图删除根行(预期的行为是数据库中的每其他行也被删除)时,我得到这个错误:
sqlite> delete from tree where objectid = '0';
Error: foreign key mismatch
我的期望与SQLite外键支持(和删除行为)可以提供不一致吗?
你的问题很简单,你在parentObjectId
上的FK引用parentObjectId
而不是objectId
, SQLite不会检测到这一点混乱,直到你尝试使用表。如果您的FK是这样定义的:
foreign key (parentObjectID) references tree(objectID) on delete cascade
从精细手册:
因此,换句话说,需要同时查看子键和父键的配置错误的外键约束是DML错误。外键DML错误的英文错误消息通常是"外键不匹配",但如果父表不存在,也可能是"没有这样的表"。如果:
,可能会报告外键DML错误
- 父表不存在,或者
- 外键约束中指定的父键列不存在,或者
- 外键约束中指定的父键列不是父表的主键,也不受惟一键的约束使用在CREATE TABLE或
中指定的排序顺序来约束- 子表引用父表的主键,但不指定主键列和主键个数父键中的列与子键列的数目不匹配。
第三点似乎适用于这里,因为parentObjectId
既不是PK也不受限制是唯一的,所以这就是为什么在您尝试修改表的内容(即使用DML语句而不是DDL语句)之前您不会看到错误的原因。