SQL约束检查是否在另一个表中输入

问题描述 投票:0回答:3

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

怎么可能实现这一目标?我是在做某事还是应采取完全不同的方法?

sql sqlite constraints
3个回答
1
投票

documentation说:

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

0
投票

你可以在'person'中为'special'和'snowflake'提供两个外键,并检查只有一个键有值。另一种解决方案可能是将“特殊”和“雪花”加入到一个表中,并检查是否只给出了“技能”或“熔点”中的一个。


0
投票

您不能使用ALTER TABLE将CHECK添加到列。

你只能使用ALTER TABLEADD一个列,然后可以有一个CHECK约束。您不能重命名列也不能删除列。

最简单的方法是在创建表时在列中定义CHECK。如果您有需要保留的数据,那么您将不得不: -

  • 1)创建一个新表,
  • 2)将数据从原始数据复制到新表中,
  • 3)重命名/删除原始和
  • 4)将新表重命名为原始表的名称。
© www.soinside.com 2019 - 2024. All rights reserved.