【问题标题】:insert several row in order to satisfy a constraint插入几行以满足约束
【发布时间】:2010-03-01 02:39:23
【问题描述】:

我有两张表:deck(id) 和 card(deck,color,value)

套牌有这些限制:

  • CHECK (fifty_two_cards_deck(id))
  • PRIMARY KEY (id)

    CREATE FUNCTION Fifth_two_cards_deck(deck integer) RETURNS boolean 语言 sql 稳定 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"

In 语句:开始事务; 插入“公共”。“甲板”(“id”) 价值观 (nextval('deck_id_seq'::regclass)); INSERT INTO "public"."card" ("deck", "颜色", "值") 值 ('1', enum_first(null::Suit), enum_first(null::Symbol));

结束交易

如何在不移除约束的情况下解决这个问题?

编辑:解决方案

感谢 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

【问题讨论】:

    标签: postgresql transactions constraints


    【解决方案1】:

    如果您将 FOREIGN KEY 设为 DEFERRABLE,然后将其设置为 DEFERRED,它可能会起作用。然后你插入“card”表,然后插入“deck”。检查约束在插入时执行(因此,在“卡”中的条目存在之前),并且不能推迟到事务结束。

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

    【讨论】:

    • 实际上,由于卡片上的主键以及颜色和值都是枚举的事实,我无法在卡片组中添加更多卡片。但我可以删除一些。我要看看触发器是否可以解决这个问题(例如,在删除行之前检查是否为 50_two_cards_deck(row.deck) 返回 true) 你为什么建议删除约束而不是修复这个问题?我一直认为约束越多(有用)越好。
    • 您可以使用触发器来修复它,但这很可能会让您遇到并发问题。删除它的原因在上面的段落中——你试图对它不打算使用的东西使用 CHECK 约束,并且其中有很多陷阱——其中只有一个是允许删除。
    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2015-08-24
    • 2018-04-11
    • 2020-07-24
    相关资源
    最近更新 更多