【发布时间】:2015-03-06 03:07:27
【问题描述】:
我想知道是否有人偶然发现了 sqlite 外键的奇怪行为。
当我更新指向另一个表主键 parcours (eid) 并被声明为外键的键变体 (parcours_id) 时,会出现我的问题。
涉及的表格有:
CREATE TABLE parcours(
eid character varying(36) PRIMARY KEY,
name character varying(50),
comment text,
location_id character varying(36),
owner_id character varying(36),
change_id integer NOT NULL,
change_flag smallint NOT NULL DEFAULT 1,
CONSTRAINT fk_location_id FOREIGN KEY (location_id)
REFERENCES location (eid)
ON UPDATE CASCADE
ON DELETE RESTRICT
)
CREATE TABLE variant (
eid character varying(36) PRIMARY KEY,
parcours_id character varying(36) NOT NULL,
name character varying(50),
comment text,
created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
active smallint NOT NULL DEFAULT 1,
selected smallint NOT NULL DEFAULT 0,
tgt_count integer NOT NULL,
owner_id character varying(36)
DEFAULT '687baa6e-556f-43f2-897a-f1dfb371541a',
change_id integer NOT NULL,
change_flag smallint NOT NULL DEFAULT 1,
CONSTRAINT fk_parcours_id FOREIGN KEY (parcours_id)
REFERENCES parcours (eid)
ON UPDATE CASCADE
ON DELETE RESTRICT
)
variant(parcours_id) 到 parcours(eid) 的外键关系在插入时完美运行,但在更新时失败
android.database.sqlite.SQLiteException: foreign key mismatch: , while compiling: UPDATE variant SET parcours_id=?,name=?,comment=?,created=?,active=?,selected=?,tgt_count=?,owner_id=?,change_id=?,change_flag=? WHERE eid=?
现在这个问题有点哲学,因为此时我不需要更新密钥变体(parcours_id),因为它没有改变。我决定只执行一次更新功能,始终更新除主键之外的所有字段。一般来说,我不希望有问题的值会改变,所以我可以将它排除在更新之外。
在我看来,我的实现没问题,因为如果我禁用数据库上的外键而不更改它的任何其他工作,则外键会正确更新,并且更新后数据库的完整性是完整的。
对我来说,这证明问题不是由我的实现引起的,但似乎是对 sqlite 如何处理外键更新的普遍误解。
有什么建议吗?
编辑: 从更新中删除关键变量(parcours_id)后,我仍然得到一个 SQLITE 异常:
android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
SQL 语句是:
UPDATE variant SET name=?,comment=?,created=?,active=?,selected=?,tgt_count=?,owner_id=?,change_id=?,change_flag=? WHERE eid=?
【问题讨论】: