SQLite插入包含NULL外键的数据时触发“Foreign key mismatch”错误的问题咨询
嘿,我来帮你捋清楚这个问题——你碰到的Foreign key mismatch - D referencing C错误,其实和NULL本身没啥关系,而是SQLite对外键约束的一个容易踩坑的规则被忽略了。
为啥会报错?
SQLite对设置外键有个硬性要求:被引用的父表列必须是主键,或者是带唯一约束的列。虽然你把表C的ID定义成了INTEGER PRIMARY KEY NOT NULL,但有个很容易被忽略的细节:如果创建表D的时候,表C还没被创建出来,那D表的外键引用会直接失效。哪怕之后再创建C表,D表的外键约束也不会自动修复,这时候插入数据就会触发这个不匹配错误。
当然还有其他小概率可能:比如你没显式开启SQLite的外键约束(不过你能触发错误说明已经开了),或者之前创建的D表结构有问题(比如SUPP字段被误设为NOT NULL),但最可能的还是表的创建顺序搞反了。
怎么修复?
我给你一步步来操作:
先检查外键约束状态
执行这条命令看看D表的外键是不是真的无效:PRAGMA foreign_key_check(D);如果返回了错误记录,那就实锤是外键约束的问题了。
删掉有问题的D表
先把旧的D表删掉,才能重新创建正确的:DROP TABLE IF EXISTS D;按正确顺序重建所有表
一定要保证先创建A、B、C,最后再创建D——这样D表创建的时候,C表已经存在,外键引用才能生效:CREATE TABLE IF NOT EXISTS A ( ID INTEGER PRIMARY KEY NOT NULL ); CREATE TABLE IF NOT EXISTS B ( ID INTEGER PRIMARY KEY NOT NULL ); CREATE TABLE IF NOT EXISTS C ( ID INTEGER PRIMARY KEY NOT NULL ); CREATE TABLE IF NOT EXISTS D ( SID INTEGER NOT NULL, DID INTEGER NOT NULL, SUPP INTEGER, PRIMARY KEY (SID, DID), FOREIGN KEY (SID) REFERENCES A (ID), FOREIGN KEY (DID) REFERENCES B (ID), FOREIGN KEY (SUPP) REFERENCES C (ID) );确认外键约束开启
虽然你之前触发了错误说明已经开启,但保险起见还是执行一下:PRAGMA foreign_keys = ON;重新执行插入
这时候再跑你的插入语句:INSERT OR REPLACE INTO D VALUES (2,5,NULL);应该就能成功了。
补充说明
顺便提一句:SQLite里,外键字段设为NULL是完全合法的,哪怕C表一条记录都没有也没关系——因为NULL值不会触发外键约束检查,所以你不用为了插入NULL去给C表加数据。
内容的提问来源于stack exchange,提问作者MegaFlipFlop

