我有两个表:deck(id)和card(deck,color,value)
甲板有这些限制:
CHECK (fifty_two_cards_deck(id))
PRIMARY KEY (id)
CREATE FUNCTION five_two_cards_deck(deck integer)RETURNS boolean LANGUAGE sql STABLE STRICT 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错误:
错误:关系“deck”的新行 违反检查约束 “fifty_two_cards_deck”
声明:开始交易; INSERT INTO“public”。“deck”(“id”) VALUES (NEXTVAL( 'deck_id_seq' :: regclass的)); INSERT INTO“public”。“card”(“deck”, “颜色”,“价值”)价值('1', enum_first(空::套装), enum_first(空::符号));
结束交易
如何在不删除约束的情况下解决此问题?
编辑:解决方案
对于Magnus 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
答案 0 :(得分:1)
如果使用DEFERRABLE创建FOREIGN KEY,然后将其设置为DEFERRED,则可能会有效。然后插入“卡”表首先,然后插入“卡座”。检查约束在插入时执行(因此,在“卡”中的条目存在之前),并且不能延迟到事务结束。
但实际上并没有解决你的约束被破坏而应该被删除的事实;)CHECK约束只会检查进入“deck”的行。但是一旦在那里插入了行,你仍然可以在“card”表中添加更多行或删除行,并且CHECK约束不会抱怨 - 直到你下次尝试修改“deck”时。