5

最初の 4 に挿入されたいくつかのレコードで定義された次の 5 つのテーブルがあります。これは、外部キー制約が有効になっている sqlite 3.7.1.7 を使用しています。

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 テーブルの 2 番目のレコードを削除しようとすると、テーブル questmc_questmcselection が定義されている限り、外部キーの不一致エラーが発生します。

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

questmc、questmcselection、および questmc_questmcselection には、この削除を妨げる関連する既存のレコードがありません。このエラーが発生する理由は何ですか?

4

2 に答える 2

4

subjectlevelこのエラーは、この特定のレコードとは関係ありません。

問題は、テーブルに必要なインデックスがないことです。このDELETEステートメントは、データベース スキーマの整合性をチェックするために SQLite を必要とする最初のコマンドだったため、以前は報告されていませんでした。

于 2013-06-09T20:19:43.453 に答える
1

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 制約の対象となるか、親テーブルの CREATE TABLE ステートメントで照合順序を [使用する] UNIQUE インデックスを持つ必要があります。

つまり、代替手段は次のとおりです。

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

(これは複数列の外部キーも強調表示します。インデックスでも機能します...)

于 2014-07-03T16:11:43.843 に答える