概述:我有一个父/子表关系,其中子表可能包含2:n个记录,FK返回到父表。尝试从父代删除时,收到SQLITE_CONSTRAINT错误。这是出乎意料的,因为我启用了FK,用ON DELETE CASCADE
注册了孩子,并且有一个足够新的SQLite版本。
然而:我的子表 * 最初 * 没有ON DELETE CASCADE
。我添加(并启用FK的)后,数据已添加到父/子。从那里,我重命名了原来的子项&创建了一个带有约束的新表,最后移到新表。
表格布局如下:
CREATE TABLE IF NOT EXISTS message (
message_id INTEGER PRIMARY KEY,
area_tag VARCHAR NOT NULL,
message_uuid VARCHAR(36) NOT NULL,
reply_to_message_id INTEGER,
to_user_name VARCHAR NOT NULL,
from_user_name VARCHAR NOT NULL,
subject, /* FTS @ message_fts */
message, /* FTS @ message_fts */
modified_timestamp DATETIME NOT NULL,
view_count INTEGER NOT NULL DEFAULT 0,
UNIQUE(message_uuid)
);
CREATE INDEX IF NOT EXISTS message_by_area_tag_index
ON message (area_tag);
CREATE VIRTUAL TABLE IF NOT EXISTS message_fts USING fts4 (
content="message",
subject,
message
);
CREATE TRIGGER IF NOT EXISTS message_before_update BEFORE UPDATE ON message BEGIN
DELETE FROM message_fts WHERE docid=old.rowid;
END;
CREATE TRIGGER IF NOT EXISTS message_before_delete BEFORE DELETE ON message BEGIN
DELETE FROM message_fts WHERE docid=old.rowid;
END;
CREATE TRIGGER IF NOT EXISTS message_after_update AFTER UPDATE ON message BEGIN
INSERT INTO message_fts(docid, subject, message) VALUES(new.rowid, new.subject, new.message);
END;
CREATE TRIGGER IF NOT EXISTS message_after_insert AFTER INSERT ON message BEGIN
INSERT INTO message_fts(docid, subject, message) VALUES(new.rowid, new.subject, new.message);
END;
CREATE TABLE IF NOT EXISTS message_meta (
message_id INTEGER NOT NULL,
meta_category INTEGER NOT NULL,
meta_name VARCHAR NOT NULL,
meta_value VARCHAR NOT NULL,
UNIQUE(message_id, meta_category, meta_name, meta_value),
FOREIGN KEY(message_id) REFERENCES message(message_id) ON DELETE CASCADE
);
字符串
在启动时,在连接到DB后,我确保启用FK:
PRAGMA foreign_keys = ON;
型
其他详情:
- SQLite版本:3.7.17
- 访问:node-sqlite3
- 精确误差:
Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed
个
这是因为我后来添加了约束吗?(请参阅更新1)如何在不丢失数据的情况下修复此问题?
更新1:
我可以确认只有选择消息(我相信,添加到message_Meta的message beforeON DELETE CASCADE
中的消息)会导致约束错误。其他人删除刚刚好,并正确地取出相关的message_Meta记录。
2条答案
按热度按时间vcirk6k61#
回答我自己的问题--经过几个小时的尝试,我找到了问题:
ON DELETE CASCADE
子句时,我将原始的message_meta
表重命名为message_meta_backup
,创建一个带有该子句的新表,然后将数据移动到其中:SELECT * FROM message_meta_backup INSERT INTO message_meta;
。我 * 没有 * 做的是删除备份表。我尝试了什么(不起作用):
REINDEX;
个DROP TABLE message_meta_backup;
个什么工作:
最后,使用
sqlite3
shell的.drop
命令删除备份表并完全重建数据库的组合才能正常工作:字符串
我现在可以使用
DELETE FROM message ...
,并让它正确地将删除级联到message_meta
,而不会出现讨厌的错误:型
(no错误提示)
vx6bjr1n2#
我只会补充说,我有这个问题时,试图删除通过Db浏览器的SQLite图形用户界面。当我从sqlite shell运行该命令时,它没有任何问题。DB浏览器必须添加一些不必要的步骤。