【问题标题】:Adding a WHERE clause to a Foreign Key将 WHERE 子句添加到外键
【发布时间】:2010-11-19 16:53:22
【问题描述】:

我的数据库 (TableA) 中有一个表,其中有一列 (TableA.Column1),它只允许来自另一个表 (TableB.Column2) 的某些行的值。除了只允许来自 TableB.Column2 的某些行之外,这与普通的外键关系非常相似。例如,我可能只允许来自 TableB.Column2 的行,其中 TableB.Column3 > 100;

有没有办法在数据库中表达这种类型的参照完整性?我尝试将 where 子句添加到外键,并尝试将子查询添加到 Check 约束。我两个都没有工作。

有人有什么建议吗?

【问题讨论】:

    标签: sql


    【解决方案1】:

    答案可能因您使用的数据库系统而异。但一个选项当然是使用触发器。

    【讨论】:

    • 只是出于好奇,这将如何工作?触发器是否会附加到 INSERT 或 UPDATE 并引发错误?我以前没有使用过触发器来确保引用完整性,希望了解详细信息。
    • @bzarah 它将同时连接到两者。而且我真的不认为您可以将其称为参照完整性检查。对我来说,这听起来更像是一条商业规则。
    • 同意,这听起来确实像一个业务规则,而不是简单的 RI。尽管这可能会起作用,但完全放弃触发器并在 App 层中强制执行不是更好吗?另外,如果将表 A 中的值更新为使表 B 中的记录无效的值,会发生什么情况?另一个触发器?
    • @bazrah,是的,这需要另一个触发器。我同意它可能会在应用程序层中强制执行。视情况而定。我经常看到没有专门 IT 知识的业务专家通过一些数据库管理 ui 破解表格的系统。
    • 感谢克劳斯的回答。你和 bzarah 都提出了一些有趣的案例,这些案例让我同意这更像是一个商业规则,而不是裁判完整性问题。实际上,我们已经在我们的应用程序层(在代码和 OR/M 映射文件中)强制执行了这一点,但我只是在寻找一种在更深层次上添加额外强制执行的方法。感谢您的帮助。
    【解决方案2】:

    如果您只允许在表 A 的列中保存“某些”值,您可以在表 B 中创建一个复合 FK,然后在您的表(表 B)中添加一个单独的检查约束?不过,这听起来像是我将在应用程序层中强制执行的那种事情。

    【讨论】:

      【解决方案3】:

      不,我认为没有办法做到这一点。

      在这种情况下,我通常最终会在被引用的表中创建一个“虚拟”条目(例如 ID = -1, Text = "state or entry unknown"),然后将这些 TableB.Column2 值设置为这个虚拟 ID 值。

      【讨论】:

        【解决方案4】:

        从数据库的角度来看,触发器似乎是最好的答案……尽管根据您的设置,这种情况可能更容易在应用层上实施。什么是向该表中插入行,是否可以对正在插入的任何内容而不是直接在数据库本身上强制执行此约束?以这种方式进行操作确实存在一些风险,但可能会更简单,具体取决于您的设置

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-07
          • 2019-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多