簡體   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