【问题标题】:How to set cascade on SQLite database with compound primary foreign key?如何使用复合主外键在 SQLite 数据库上设置级联?
【发布时间】:2011-03-20 20:43:28
【问题描述】:

我有一个由超类型表和子类型表构成的数据库,如下所示:

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..从我看到的示例中看起来它应该如何工作......

【问题讨论】:

    标签: sqlite foreign-keys relational-database cascading-deletes compound-key


    【解决方案1】:

    这是因为您设置了无效的外键。尽管 SQLite 允许您设置它,但在尝试执行它时会出错。

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

    在外键约束中命名的父键列不是父表的主键,并且不受使用 CREATE TABLE 中指定的排序顺序的唯一约束

    应针对唯一目标设置外键。 PatientId references Event(PatientID) 列无效,因为仅在表 Event 中的 PatientID 不是唯一的。


    编辑

    外键支持仅适用于 SQLite 3.6.19 或更高版本。根据您使用的工具,您还需要显式启用pragma foreign_keys。例如,对于 Firefox 的 SQLite 管理器插件,请参阅此处http://code.google.com/p/sqlite-manager/wiki/ForeignKeys


    这对我有用
    注意!!如果现有表格包含任何重要内容,请不要删除它们。尝试新的数据库
    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;
    

    【讨论】:

    • 没有一个字段本身必须是唯一的,因此复合键...所有 3 个肯定是唯一的。有什么办法可以使这项工作?我可以从 Patient_id 中删除 FK 吗?不过,那将是不准确的。
    • @Damon 如果您的意思是在 3 个字段上设置 FK,请设置一 (1) 个 FK,而不是三 (3) 个单独的 FK。
    • 啊 k.. 没有意识到这是这样做的方法,但我仍然遇到级联问题.. 如果可以的话,我更新了问题中的代码和结果描述看看?
    • @Damon - 请查看扩展答案
    • @Richard aka cyberkiwi:它适用于我在 3.7.4 下,但前提是我使用 pragma foreign_keys=on,这是我所期望的。编译 SQLite 合并时,默认情况下不启用外键支持。我不记得这是否受编译时设置的控制。 (今晚看太累了。)
    猜你喜欢
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2013-10-06
    相关资源
    最近更新 更多