【问题标题】:Can I have a foreign key referencing a column in a view in SQL Server?我可以有一个外键引用 SQL Server 视图中的列吗?
【发布时间】:2010-10-01 14:52:10
【问题描述】:

在 SQL Server 2008 中并给出

TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)

是否可以定义TableZ(A_or_B_ID, Z_Data) 使得Z.A_or_B_ID 列被限制为ViewC 中的值?这可以使用针对视图的外键来完成吗?

【问题讨论】:

    标签: sql-server view foreign-keys


    【解决方案1】:

    您不能在外键中引用视图。

    【讨论】:

    • 这是 SQL Server 的限制还是不合理的事情?
    • @Brian 我也很想知道这是 SQL Server 的限制还是想要的不合理的东西,因为此时我将使用触发器来模拟视图以获取 FK支持(虽然我使用的是 MySql)。
    • 这是对这些后续问题的一个很好的回答 - stackoverflow.com/questions/3833150/…
    • 我不确定这对这些问题有什么好的答案...它是关于不同的 DBMS 并说视图旨在隐藏架构细节和用户方便。首先,好的……但这并不是在初始设计之外找到可靠用例的第一件事。其次,我不确定为什么 FK 不会那样做。视图可以是任何查询,甚至不必从表中提取,也可以是一堆结合在一起的常量……在这种情况下,外键似乎非常明智。如果有原因,我希望有更深层次的东西。
    【解决方案2】:

    在较旧的 SQL Server 版本中,外键只能通过触发器实现。您可以通过创建一个插入触发器来模拟自定义外键,该触发器检查插入的值是否也出现在相关表之一中。

    【讨论】:

    • 欢迎来到 StackOverflow。我发现你的答案很有价值,因为它提供了一种解决方法,但正确的答案是公认的答案,而且这个问题已有 4 年以上的历史了,所以我只是不投票,但不想在没有这个评论的情况下离开。
    【解决方案3】:

    如果你真的需要 TableZ 中的A_or_B_ID,你有两个类似的选择:

    1) 将可空的A_IDB_ID 列添加到表z,在这两个列上使用ISNULL 使A_or_B_ID 成为计算列,并添加一个CHECK 约束,使得只有A_IDB_ID 之一不为空

    2) 向表 z 添加一个 TableName 列,限制为包含 A 或 B。现在创建 A_IDB_ID 作为计算列,它们仅在其相应的表被命名时才非空(使用 CASE 表达式)。让他们也坚持下去

    在这两种情况下,您现在都有 A_IDB_ID 列,它们可以有适当的外部 基表的键。不同之处在于计算哪些列。还有,你 如果 2 个 ID 列的域不需要,则不需要上面选项 2 中的 TableName 重叠 - 只要您的案例表达式可以确定哪个域 A_or_B_ID 落入

    (感谢评论修复我的格式)

    【讨论】:

    • 将带下划线的单词放在反引号中:A_or_B_ID
    • 我正在努力为遗留系统添加一些功能,这是将新旧系统修补在一起的好方法。谢谢!
    【解决方案4】:

    抱歉,您不能 FK 到 SQL Server 中的视图。

    【讨论】:

      【解决方案5】:

      还有另一种选择。将TableATableB 视为名为@9​​87654323@ 的新表的子类。调整 TableB 的 ID 值,使其与 TableA 的 ID 值不一致。将 TablePrime 中的 ID 设置为 PK 并将所有 TableATableB 的(调整后的)ID 插入 TablePrime。使TableATableB 在其PK 上与TablePrime 中的相同ID 具有FK 关系。

      您现在拥有超类型/子类型模式,并且可以对TablePrime(当您想要要么-A-或-B)或单个表之一(当您想要只有A或只有B)。

      如果您需要更多详细信息,请询问。有一些变化可以让你确保 A 和 B 是互斥的,或者你正在使用的东西可以同时是两者。如果可能,最好在 FK 中将其正式化。

      【讨论】:

        【解决方案6】:

        添加一个引用用户定义函数的约束更容易,fCheckIfValueExists(columnValue) 如果值存在则返回 true,如果不存在则返回 false。

        好处是它可以接收多个列,使用它们执行计算,接受空值并接受不精确对应主键或与连接结果进行比较的值。

        缺点是优化器不能使用他所有的外键技巧。

        【讨论】:

        • 缺点是优化器不能使用他所有的外键技巧... ...并且该函数将为您插入/更新的每一行运行(所以不太适合套装)。
        【解决方案7】:

        对不起, 从严格意义上讲,不,您不能在视图上设置外键。原因如下:

        InnoDB 是 MySQL 唯一具有外键的内置存储引擎。任何 InnoDB 表都将在 information_schema.tables 中注册,其中 engine = 'InnoDB'。

        视图虽然注册在 information_schema.tables 中,但具有 NULL 存储引擎。 MySQL 中没有任何机制可以在具有未定义存储引擎的任何表上拥有外键。

        谢谢!

        【讨论】:

        • 这个问题是关于sql server的
        猜你喜欢
        • 2010-10-19
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多