2013-06-09 1 views
3

У меня есть следующие 5 таблиц, определенных с несколькими записями, вставленными в 1-й 4. Это использование sqlite 3.7.1.7 с включенным константой внешнего ключа.несоответствие внешнего ключа при команде delete для несвязанной записи

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 не имеют соответствующих существующих записей, которые должны предотвратить это удаление. Любая идея, почему эта ошибка возникает?

+0

Это, как представляется, не так, как последние 2 внешних ключей определенную в таблице questmc_questmcselection. Я удалил последний, а затем второй, чтобы последний (оба ключа (subject_id, subjectlevel_id)). Итак, это приводит к вопросу: «поддерживает ли sqlite 3.7.1.7 несколько ссылок внешнего ключа в одну и ту же таблицу? – rss181919

+0

Может быть, я должен задать более крупный вопрос. У меня есть таблица вопросов с несколькими вариантами выбора (mc) и таблица выбора, в которой есть варианты, которые могут быть повторно использованы для разных вопросов. Мне нужна связь n: n между ними. Однако как в вопросе, так и в записи выбора есть тема и определение уровня детализации.Я должен застраховать n: n привязка только позволяет связывать одинаковые типы.Как я могу это сделать на уровне db? – rss181919

ответ

2

Эта ошибка не имеет ничего общего с данным номером subjectlevel.

Ваша проблема заключается в том, что вашим столам не хватает the required indexes. Об этом не сообщалось ранее, потому что оператор DELETE был первой командой, которая требовала SQLite для проверки согласованности схемы базы данных.

+0

Я совершенно новичок в SQLite и несколько новичок в SQL. Какие индексы необходимы для выполнения этой работы ? – rss181919

+0

Я не знаю, возможно ли то, что я пытаюсь сделать, на уровне db. В таблице A есть идентификатор и поле типа. В таблице B есть идентификатор и поле типа. В обоих случаях id является первичным ключом и тип имеет значения, которые одинаковое значение. таблица C обеспечивает связь n: n между A & B. Тем не менее, я хочу только ссылку, если записи A & B имеют один и тот же тип. – rss181919

+1

Получил это с помощью CL. Таблицы A и B должны включать идентификатор и тип ключа. Это уникальные индексы, на которые ссылался CL. Таблица C должна включать 3 поля (помощь, ставка, тип) и 2 ограничения fkey следующим образом. внешний ключ (помощь, тип) ссылка A (идентификатор, тип), внешний ключ (ставка, тип) ссылка B (id, type) Это позволяет связать 2 записи из A и B в таблицу C только в том случае, если они разделяют то же значение типа. Спасибо за помощь. – rss181919

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> _ 

Из документации:

Обычно родительский ключ внешнего ключа является первичным ключом родительской таблицы. Если [нет], то столбцы родительского ключа должны быть вместе с ограничением 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)); 

(это также выдвигает на первый план несколько столбцов внешних ключи, они работают с индексами тоже ...)

 Смежные вопросы

  • Нет связанных вопросов^_^