简体   繁体   English

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

[英]SQL constraint check if entry in another table

Based on an integer ID, how can one constrain two tables referencing a common table from including the same element already in the other table?基于整数 ID,如何限制引用公共表的两个表不包含另一个表中已经存在的相同元素?

A basic table of, let's say personal information is created:假设创建了个人信息的基本表:

CREATE TABLE person (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    info VARCHAR(10)
);

Then two tables referencing person is created:然后创建了两个引用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)
);

However, I want to constrain the two tables from including the same person.但是,我想限制两个表包含同一个人。

So I thought something like this would do the trick, but SQLite3 gives syntax errors (near CHECK).所以我认为这样的事情可以解决问题,但是 SQLite3 给出了语法错误(在 CHECK 附近)。

ALTER TABLE special ADD CHECK (
    (SELECT COUNT(*) FROM snowflake WHERE snowflake.id = special.id) = 0
);

OR based on this answer或基于此答案

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

How might this be achieved?这如何实现? Am I onto something or should an entirely different approach be taken?我是在做某事还是应该采取完全不同的方法?

The documentation says:文档说:

The expression of a CHECK constraint may not contain a subquery. CHECK 约束的表达式可能不包含子查询。

So you have to use trigger s:所以你必须使用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

You could have two foreign keys in 'person' to both 'special' and 'snowflake' and a check that only one of the keys has a value.您可以在“person”中有两个外键,分别指向“special”和“snowflake”,并检查只有一个键具有值。 Another solution could be to join 'special' and 'snowflake' into one table and have a check that only one of 'skill' or 'meltingpoint' is given.另一种解决方案可能是将“特殊”和“雪花”加入一个表中,并检查是否只给出了“技能”或“熔点”中的一个。

You cannot use ALTER TABLE to add a CHECK to a column.不能使用ALTER TABLE向列添加CHECK

You can only use ALTER TABLE to ADD a column which can then have a CHECK constraint.您只能使用ALTER TABLE ADD一列,然后该列可以具有CHECK约束。 You cannot rename a column nor delete a column.您不能重命名列或删除列。

The easiest method would be to define the CHECK in the column when creating the table.最简单的方法是在创建表时在列中定义 CHECK。 If you have data that needs to be kept, then you will have to :-如果您有需要保留的数据,那么您将必须:-

  • 1)create a new table, 1)创建一个新表,
  • 2) copy the data from the original to the new table, 2)将原表的数据复制到新表中,
  • 3) rename/drop the original and 3)重命名/删除原来的和
  • 4) rename the new table to the name of the original table. 4)将新表重命名为原表的名称。

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

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