插入几行以满足约束

时间:2010-03-01 02:39:24

标签: postgresql transactions constraints

我有两个表: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

1 个答案:

答案 0 :(得分:1)

如果使用DEFERRABLE创建FOREIGN KEY,然后将其设置为DEFERRED,则可能会有效。然后插入“卡”表首先,然后插入“卡座”。检查约束在插入时执行(因此,在“卡”中的条目存在之前),并且不能延迟到事务结束。

但实际上并没有解决你的约束被破坏而应该被删除的事实;)CHECK约束只会检查进入“deck”的行。但是一旦在那里插入了行,你仍然可以在“card”表中添加更多行或删除行,并且CHECK约束不会抱怨 - 直到你下次尝试修改“deck”时。