我试图在SQLite中使用外键支持来维护具有自反连接的单表数据库的引用完整性。
e.g。
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外键支持(和删除行为)可以提供的一致吗?
答案 0 :(得分:2)
您的问题非常简单,您的FK parentObjectId
引用parentObjectId
而不是objectId
,而SQLite在您尝试使用该表之前未检测到这种混淆。如果您的FK定义如下:
foreign key (parentObjectID) references tree(objectID) on delete cascade
来自fine manual:
因此,换句话说,需要同时查看子项和父项的配置错误的外键约束是DML错误。外键DML错误的英语错误消息通常是“外键不匹配”,但如果父表不存在,也可以是“没有这样的表”。如果出现以下情况,可能会报告外键DML错误:
- 父表不存在,或
- 外键约束中指定的父键列不存在,或
- 外键约束中指定的父键列不是父表的主键,并且不受唯一的约束 约束使用CREATE TABLE中指定的整理顺序,或
- 子表引用父键的主键,而不指定主键列和主键数 父级中的列与子键列的数量不匹配。
第三点似乎适用于此处,因为parentObjectId
既不是PK也不是唯一的约束,这就是为什么在尝试修改表的内容之前看不到错误的原因(即使用DML语句)而不是DDL声明。)