繁体   English   中英

SQL 约束检查是否在另一个表中的条目

[英]SQL constraint check if entry in another table

基于整数 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
);

或基于此答案

ALTER TABLE special ADD CHECK (
    NOT EXISTS (SELECT 1 FROM snowflake WHERE snowflake.ID = special.ID)
);

这如何实现? 我是在做某事还是应该采取完全不同的方法?

文档说:

CHECK 约束的表达式可能不包含子查询。

所以你必须使用trigger s:

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。 如果您有需要保留的数据,那么您将必须:-

  • 1)创建一个新表,
  • 2)将原表的数据复制到新表中,
  • 3)重命名/删除原来的和
  • 4)将新表重命名为原表的名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM