我有兩個表:甲板(ID)和卡(甲板,顏色,值)插入幾個行以滿足約束
甲板具有這些約束:
CHECK (fifty_two_cards_deck(id))
PRIMARY KEY (id)
CREATE FUNCTION fifty_two_cards_deck(甲板整數)返回Boolean 語言SQL STABLE嚴格 AS $ $ SELECT COUNT(*)= 52 FROM card WHERE deck = $ 1 $ $;
和卡有這些約束:
FOREIGN KEY (deck) REFERENCES deck(id)
PRIMARY KEY (deck, color, value)
我怎樣才能插入一個新的平臺?
我嘗試這樣做:
begin transaction;
INSERT INTO "public"."deck" ("id") VALUES (nextval('deck_id_seq'::regclass));
INSERT INTO "public"."card" ("deck", "color", "value") VALUES ('1', enum_first(null::Suit), enum_first(null::Symbol));
end transaction
(我不得不編輯fifty_two_cards_deck
是用於測試目的的one_card_deck
) 但我得到這個錯誤:
SQL error:
ERROR: new row for relation "deck" violates check constraint "fifty_two_cards_deck"
In statement: begin transaction; INSERT INTO "public"."deck" ("id") VALUES (nextval('deck_id_seq'::regclass)); INSERT INTO "public"."card" ("deck", "color", "value") VALUES ('1', enum_first(null::Suit), enum_first(null::Symbol));
end transaction
我怎樣才能解決這個無需拆卸限制?
編輯:解
THX馬格納斯Hagander我得到它的工作是這樣的(設置外鍵可延遲後):
begin transaction;
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO "public"."deck-card" ("deck", "position", "color", "value") VALUES (1, 0, enum_first(null::suit), enum_first(null::Symbol));
INSERT INTO "public"."deck" ("id") VALUES (1);
end transaction
實際上,由於卡片上的主鍵以及顏色和值都是枚舉這一事實,我無法在卡組中添加更多卡片。但我可以刪除一些。 我要看看觸發器是否可以解決這個問題(例如,在刪除行之前檢查fifty_two_cards_deck(row.deck)是否返回true) 爲什麼建議刪除約束而不是修復此問題?我一直認爲更有用的限制是他最好的。 – Mathieu 2010-03-01 11:24:01
您可以使用觸發器修復它,但這可能會讓您陷入併發問題。刪除它的原因是在上面的段落中 - 你試圖使用一個CHECK約束來實現它不打算做的事情,並且有很多陷阱 - 其中只有一個允許DELETE。 – 2010-03-01 22:20:04