0

首先,我想谈谈外键约束规则以及它的帮助。假设我有两个表,一个主表的主列称为 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 查询,则相反的方式并不是真正必要的,但是谁能确定呢?引发错误是一种提醒我们修复和更正并使其准确运行而不会损坏数据的机制,并且错误可以t是隐形的。

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

您的帮助将不胜感激。

PS:我真的很喜欢 SQLite,因为它是基于文件的,易于部署,支持大文件大小(比 SQL Server Ce 有优势),但是一些缺失的功能让我重新思考了很多次,我害怕如果去的话,我的应用程序可能不可靠并且无法预料地损坏。

4

1 回答 1

1

回答您巧妙地隐藏在您的咆哮中的问题:SQLite 允许触发器内部的RAISE函数;由于缺少控制流语句,这必须与 a 一起使用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;
于 2013-04-06T08:57:52.340 回答