不相关记录的删除命令的外键不匹配

时间:2013-06-09 19:30:18

标签: sqlite foreign-keys mismatch

我有以下5个表定义了一些记录插入到第一个4中。这是使用sqlite 3.7.1.7启用了外键constaint。

create table if not exists subject (id varchar(50) primary key,desc varchar(100));
insert into subject (id,desc) values ("subject1","test subject");

create table if not exists subjectlevel (id_subject_id varchar(50) references subject(id) on delete cascade, id integer not null, desc varchar(100) not null, questmcmaxselections integer not null, primary key (id_subject_id,id));

insert into subjectlevel (id_subject_id,id,desc,questmcmaxselections) values ("subject1",1,"test subject1 level 1",4);

insert into subjectlevel (id_subject_id,id,desc,questmcmaxselections) values ("subject1",2,"test subject1 level 2",4);

create table if not exists questmc (id integer primary key, text varchar(300) not null, includeallanswers int not null, subject_id varchar(50), subjectlevel_id integer, foreign key (subject_id, subjectlevel_id) references subjectlevel (id_subject_id,id) on delete cascade); 

insert into questmc (text,includeallanswers,subject_id,subjectlevel_id) values ("this is a _ question", 1, "subject1",1);

create table if not exists questmcselection (id integer primary key, text varchar(100) not null, subject_id varchar(50), subjectlevel_id integer, foreign key (subject_id, subjectlevel_id) references subjectlevel (id_subject_id,id) on delete cascade);

insert into questmcselection (text,subject_id,subjectlevel_id) values ("this is a solution","subject1",1);

create table if not exists questmc_questmcselection(id integer primary key, answer integer not null, questmc_id integer, questmcselection_id integer, subject_id varchar(50), subjectlevel_id integer, foreign key (questmc_id) references questmc(id) on delete cascade, foreign key (questmcselection_id) references questmcselection (id) on delete cascade, foreign key (subject_id,subjectlevel_id) references questmc (subject_id,subjectlevel_id) on delete cascade, foreign key (subject_id,subjectlevel_id) references questmcselection (subject_id,subjectlevel_id));

如果我尝试删除subjectlevel表中的第二条记录,只要定义了表questmc_questmcselection,就会出现外键不匹配错误。

sqlite> delete from subjectlevel where id=2;
Error: foreign key mismatch - "questmc_questmcselection" referencing "questmcselection"

questmc,questmcselection和questmc_questmcselection没有相关的现有记录可以阻止此删除。知道为什么会出现这个错误吗?

2 个答案:

答案 0 :(得分:2)

此错误与此特定subjectlevel记录无关。

您的问题是您的表格缺少the required indexes。 之前没有报告过,因为DELETE语句是第一个要求SQLite检查数据库模式一致性的命令。

答案 1 :(得分:0)

基于CL的答案 -

sqlite> create table parent(a);
sqlite> create table child(a, FOREIGN KEY (a) REFERENCES parent(a));
sqlite> pragma foreign_keys = ON;
sqlite> insert into parent values(3);
sqlite> insert into child values (3);
Error: foreign key mismatch - "child" referencing "parent"
sqlite> create unique index p_a on parent(a);
sqlite> insert into child values (3);
sqlite> _

来自文档:

  

通常,外键约束的父键是主键   父表的。如果[not],那么父键列必须是   统一受UNIQUE约束或具有UNIQUE索引[使用]   CREATE TABLE中的归类序列....   父表的语句。

即。替代方案是:

sqlite> create table parent(a, b, UNIQUE (a, b));
sqlite> create table child (x, y, FOREIGN KEY (x, y) REFERENCES parent(a, b));

(这也突出了多列外键;它们也适用于索引......)