【问题标题】:Oracle foreign key constraint questionoracle外键约束问题
【发布时间】:2011-04-15 17:54:29
【问题描述】:

我需要在某个表 B 上定义一个外键约束,其中列 ID 必须在表 A.ID 的集合中 OR 它可能为 NULL(这也是有效值)。

(A.ID列不能同时为NULL)。

我应该使用 CHECK 子句吗?

UPD:对不起,我写错了。我的意思是:

我需要在某个表 B 上定义一个外键约束,其中列 ID 必须在表 A.ID 的集合中 OR 它可能是 (这将也是有效值)。

(A.ID 列不能同时)。

【问题讨论】:

    标签: sql oracle foreign-keys constraints


    【解决方案1】:

    是的。

    除非您插入 A.ID = 0 的行,否则外键约束将不起作用。

    【讨论】:

      【解决方案2】:

      只需创建一个FOREIGN KEY 约束。 B.ID 可能仍然是 NULL

      您可以在 psoug 上找到一些示例

      我不建议存储 0 而不是 NULL0 在关系数据中没有语义,手动的CHECK 约束将更难维护,而且性能可能会低很多,因为 Oracle 的基于成本的优化器可能无法将其用于查询转换。最好将NULL 插入到外键列中,并可能使用这些等效表达式中的任何一个来读取它:

      NVL(B.ID, 0)
      DECODE(B.ID, NULL, 0, B.ID)
      CASE B.ID WHEN NULL THEN 0 ELSE B.ID END
      

      【讨论】:

      • 奇怪,但我收到此错误:ORA-02091:事务回滚 ORA-02291:违反完整性约束 (ENWIKI.REVISION_FK2) - 在...中找不到父键
      • 这意味着您要在B.ID 中插入一个值,该值在A.ID 中(还没有?)存在。另一方面,您可能有一个完全不同的外键,这导致了问题?
      • 我不建议这样做。最好将NULL 插入外键列并可能这样读取:NVL(B.ID, 0) = DECODE(B.ID, NULL, 0, B.ID) = CASE B.ID WHEN NULL THEN 0 ELSE B.ID END
      • 我同意 Lukas 的观点:不要在这类事情上使用“神奇”数字。
      【解决方案3】:

      如果我理解正确的话,你不需要检查约束。只是一个普通的可空列,具有引用 A.ID 的外键。这样,接受的值都是 A.ID 中的所有值,并且为 NULL。

      更新答案,问题更新后:如果不能在 A.ID 中插入值 0,则不能使用外键。但正如其他人所说,这不是推荐的做法 - 最好在 A.ID 中插入 0 值并创建外键,或者使用 NULL 代替表 B 中的 0。

      【讨论】:

        猜你喜欢
        • 2013-08-12
        • 2020-07-09
        • 2020-03-16
        • 2010-12-07
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        相关资源
        最近更新 更多