Postgresql 插入几行以满足约束

Postgresql 插入几行以满足约束,postgresql,transactions,constraints,Postgresql,Transactions,Constraints,我有两张桌子:牌组(id)和牌组(牌组、颜色、价值) 我有这些限制: CHECK(五十二张卡片卡(id)) 主键(id) 创建函数五十二张卡片(卡片组整数)返回布尔值 语言sql稳定严格 作为$$SELECT COUNT(*)从卡片中选择52,其中卡片组=1$$ 卡有以下限制: 外键(组)引用组(id) 主键(组、颜色、值) 如何插入一个新的甲板 我试过这个: begin transaction; INSERT INTO "public"."deck" ("id") VALUES (ne

我有两张桌子:牌组(id)和牌组(牌组、颜色、价值)

我有这些限制:

  • CHECK(五十二张卡片卡(id))
  • 主键(id)

    创建函数五十二张卡片(卡片组整数)返回布尔值 语言sql稳定严格 作为$$SELECT COUNT(*)从卡片中选择52,其中卡片组=1$$

卡有以下限制:

  • 外键(组)引用组(id)
  • 主键(组、颜色、值)
如何插入一个新的甲板

我试过这个:

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
(为了测试的目的,我将
52张卡片
编辑成
1张卡片
) 但我有一个错误:

SQL错误:

错误:关系“组”的新行 违反检查约束 “五十二张牌”

在报表中:开始交易; 插入“公共”。“甲板”(“id”) 价值观 (nextval(‘甲板id’::regclass)); 插入“公共”、“卡片”(“卡片组”)中, “颜色”、“值”)值('1', 首先枚举(null::Suit), enum_first(null::Symbol))

结束交易

如何在不删除约束的情况下解决此问题

编辑:解决方案

thx给Magnus Hagander我让它像这样工作(在设置外键延迟后):


如果将外键设为可延迟,然后将其设置为延迟,则可能会起作用。然后,首先将其插入“卡片”表,然后插入“卡片组”。检查约束在插入时执行(因此,远远早于“卡”中的条目存在),并且不能延迟到事务结束


但实际上,这并不能解决您的约束已被打破且应被删除的事实;)该检查约束将只检查进入“deck”的行。但是,一旦将行插入其中,您仍然可以在“card”表中添加更多行或从中删除行,并且检查约束不会抱怨-直到下次您尝试修改“deck”。

实际上,由于卡上的主键以及颜色和值为enum的事实,我无法向一个deck添加更多的卡。但我可以删除一些。我将看看触发器是否可以解决这个问题(例如,在删除行之前检查52张卡片(row.deck)是否返回true),为什么建议删除约束而不是修复此问题?我一直认为约束越多(越有用)越好。你可以用触发器来修复它,但这可能会让你陷入并发问题。删除它的原因在上面的一段中-您试图对它不打算使用的内容使用检查约束,并且其中有很多陷阱-其中之一就是允许删除。
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