在SQLite中使用TRIGGER无法解决这个外键约束规则?

时间:2013-04-05 21:03:36

标签: database sqlite triggers

首先,我想谈谈外键约束规则及其有用性。假设我有两个表,一个主表的主列名为ID,另一个表是外表,也有一个名为ID的主列。外表中的此列引用主表中的ID列。如果我们不在这些表之间建立任何外键关系/约束,我们可能会因与完整性相关的许多问题而犯规。

如果我们为它们创建外键关系,对主表中ID列的任何更改都将“自动”反映到外表中的ID列,此处的更改可以通过DELETE,UPDATE查询进行。此外,对外表中的ID的任何更改都应该受主表中的ID列的约束,例如,除非确实存在,否则不应在外表的ID列中插入或更新任何新值。 在主表的ID列中。

我知道SQLite不支持外键约束(具有上面详述的完整功能),我必须使用TRIGGER来解决这个问题。我已经使用TRIGGER以一种方式成功解决(对主表中的ID列的任何更改都将反映到外表中的ID列)但反向(如果发生混乱则应抛出/引发任何错误)例如,主表的ID列中只有值1,2,3,但外表的ID列中的值2更新为4 - >主表中不存在 - >应该抛出错误)并不容易。难点是 SQLite也不支持IF语句和RAISERROR函数。如果支持这些功能,我可以轻松解决。

我想知道如果它不支持某些重要功能,你如何使用SQLite?即使使用TRIGGER工作也不容易,我认为这是不可能的,除了你不关心反向的方式。 (事实上​​,如果你仔细设置你的SQL查询,但是谁可以确定,反向的方式并不是必需的?提升错误是一种机制,提醒我们修复和纠正并使其正常工作而不会破坏数据和错误不能隐藏

如果你仍然不知道我想要什么,我想有一些最后的话,我的目的是实现外键约束的全部功能,这在SQLite中是不受支持的(即使你可以创建这样的关系,但它是假的,不是真实的,因为你可以从SQL Server,SQL Server Ce,MS Access或MySQL中受益。

我们非常感谢您的帮助。

PS:我真的很喜欢SQLite,因为它基于文件,易于部署,支持大文件大小(优于SQL Server Ce的优势)但是一些缺少的功能让我多次重复思考,我担心如果为此,我的申请可能不可靠并且不可预测地腐败。

1 个答案:

答案 0 :(得分:1)

回答你巧妙地隐藏在你的咆哮中的问题: SQLite允许RAISE function内部触发器;由于缺少控制流语句,因此必须与SELECT

一起使用
CREATE TRIGGER check_that_id_exists_in_parent
BEFORE UPDATE OF id ON child_table
FOR EACH ROW
BEGIN
    SELECT RAISE(ABORT, 'parent ID does not exist')
    WHERE NOT EXISTS (SELECT 1
                      FROM parent_table
                      WHERE id = NEW.id);
END;