基于整数ID,如何限制引用公共表的两个表包含另一个表中已有的相同元素?
一个基本表格,假设创建了个人信息:
CREATE TABLE person (
id INTEGER PRIMARY KEY AUTOINCREMENT,
info VARCHAR(10)
);
然后创建两个引用person
的表:
CREATE TABLE special (
id INTEGER PRIMARY KEY,
skill VARCHAR(10),
FOREIGN KEY (id) REFERENCES person(id)
);
CREATE TABLE snowflake (
id INTEGER PRIMARY KEY,
meltingpoint DECIMAL,
FOREIGN KEY (id) REFERENCES person(id)
);
但是,我想限制两个表包括同一个人。
所以我认为这样的事情可以解决问题,但SQLite3会产生语法错误(接近CHECK)。
ALTER TABLE special ADD CHECK (
(SELECT COUNT(*) FROM snowflake WHERE snowflake.id = special.id) = 0
);
或者基于this answer
ALTER TABLE special ADD CHECK (
NOT EXISTS (SELECT 1 FROM snowflake WHERE snowflake.ID = special.ID)
);
怎么可能实现这一目标?我是在做某事还是应采取完全不同的方法?
CHECK约束的表达式可能不包含子查询。
所以你必须使用triggers:
CREATE TRIGGER no_snowflake_if_special
AFTER INSERT ON snowflake
WHEN EXISTS (SELECT * FROM special WHERE id = NEW.id)
BEGIN
SELECT RAISE(FAIL, "a special with the same ID already exists");
END;
-- same for special
你可以在'person'中为'special'和'snowflake'提供两个外键,并检查只有一个键有值。另一种解决方案可能是将“特殊”和“雪花”加入到一个表中,并检查是否只给出了“技能”或“熔点”中的一个。
您不能使用ALTER TABLE
将CHECK添加到列。
你只能使用ALTER TABLE
到ADD
一个列,然后可以有一个CHECK
约束。您不能重命名列也不能删除列。
最简单的方法是在创建表时在列中定义CHECK。如果您有需要保留的数据,那么您将不得不: -