Как установить каскад в базе данных SQLite с составным первичным внешним ключом? - PullRequest
1 голос
/ 20 марта 2011

У меня есть БД, которая структурирована с таблицей супертипа, а также с таблицами подтипов, например:

EVENT
PatientId INTEGER,
DateTime TEXT,
EventTypeCode TEXT,
PRIMARY KEY( PatientId, DateTime, EventTypeCode )

Различные типы событий имеют свои собственные таблицы и имеют один и тот же первичный ключ, за исключением того, что он является внешним.

EXERCISE
PatientId INTEGER,
DateTime TEXT,
EventTypeCode TEXT,
PRIMARY KEY( PatientId, DateTime, EventTypeCode ) ON CONFLICT IGNORE,
CONSTRAINT "PrimaryKey" FOREIGN KEY ("PatientId", "EventTypeCode", "DateTime") REFERENCES "Event" ("PatientId", "EventTypeCode", "DateTime") ON DELETE CASCADE ON UPDATE CASCADE

Когда я пытаюсь удалить запись в событии, я получаю несоответствие внешнего ключа, и когда я удаляю его в упражнении, он удаляет, но только в упражнении .. он не каскадируется. Что мне нужно сделать, чтобы каскад работал правильно? Я бы предпочел удалить запись в Event и использовать ее каскадно для Exercise ... что из примеров, которые я видел, похоже на то, как оно должно работать ...

1 Ответ

1 голос
/ 21 марта 2011

Это потому, что вы установили неверный внешний ключ.Несмотря на то, что SQLite позволяет вам настроить его, он будет выдавать ошибку при попытке принудительного применения.

http://www.sqlite.org/foreignkeys.html#fk_indexes

Столбцы родительского ключа, названные в ограничении внешнего ключа, не являютсяпервичный ключ родительской таблицы и не подчиняется уникальному ограничению с использованием последовательности упорядочения, указанной в CREATE TABLE

Внешние ключи должны быть настроены для уникальной цели.Столбец PatientId references Event(PatientID) недопустим, так как PatientID один в таблице Event не является уникальным.


РЕДАКТИРОВАТЬ

Поддержка внешнего ключа доступна только в SQLite 3.6.19 или более поздней версии.В зависимости от того, какой инструмент вы используете, вам также нужно явно включить pragma foreign_keys .Например, для надстройки SQLite Manager для Firefox см. Здесь http://code.google.com/p/sqlite-manager/wiki/ForeignKeys


Это работает для меня
Внимание !! не удаляйте существующие таблицы, если онисодержать что-нибудь важное.Попробуйте новый db
drop table if exists event;
drop table if exists exercise;

create table EVENT (
PatientId INTEGER,
DateTime TEXT,
EventTypeCode TEXT,
PRIMARY KEY( PatientId, DateTime, EventTypeCode ));
create table EXERCISE(
PatientId INTEGER,
DateTime TEXT,
EventTypeCode TEXT,
PRIMARY KEY( PatientId, DateTime, EventTypeCode ) ON CONFLICT IGNORE,
CONSTRAINT "PrimaryKey" FOREIGN KEY ("PatientId", "EventTypeCode", "DateTime") REFERENCES "Event" ("PatientId", "EventTypeCode", "DateTime") ON DELETE CASCADE ON UPDATE CASCADE);
insert into Event (patientid, datetime, eventtypecode) values (1,2,3);
insert into Event (patientid, datetime, eventtypecode) values (4,5,6);
insert into Event (patientid, datetime, eventtypecode) values (7,9,8);
insert into Exercise (patientid, datetime, eventtypecode) values (1,2,3);
insert into Exercise (patientid, datetime, eventtypecode) values (7,9,8);

delete from event where patientid=1;
...