Sql server 我是否可以在SQL Server的视图中有一个引用列的外键?

Sql server 我是否可以在SQL Server的视图中有一个引用列的外键?,sql-server,view,foreign-keys,Sql Server,View,Foreign Keys,在SQL Server 2008中,并给出 TableA(A_ID, A_Data) TableB(B_ID, B_Data) ViewC(A_or_B_ID, A_or_B_Data) 是否可以定义TableZ(A_或B_ID,Z_数据),以便Z.A_或B_ID列被约束为ViewC中的值?可以使用外键对视图执行此操作吗?您不能在外键中引用视图。很抱歉,您不能在SQL Server中FK到视图。如果您确实需要TableZ中的a_或B_ID,您有两个类似的选项: 1) 将可为空的A_ID和B_I

在SQL Server 2008中,并给出

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

是否可以定义
TableZ(A_或B_ID,Z_数据)
,以便
Z.A_或B_ID
列被约束为
ViewC
中的值?可以使用外键对视图执行此操作吗?

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

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

如果您确实需要TableZ中的
a_或B_ID
,您有两个类似的选项:

1) 将可为空的
A_ID
B_ID
列添加到表z中,在这两列上使用ISNULL创建
A_或B_ID
计算列,并添加一个检查约束,以使
A_ID
B_ID
中只有一个不为空

2) 向表z添加一个TableName列,该列被约束为包含a或B。现在创建
a_ID
B_ID
作为计算列,这些列只有在命名相应的表时才是非空的(使用大小写表达式)。让他们也坚持下去

在这两种情况下,您现在都有
A_ID
B_ID
列,它们可以具有适当的外部属性 基本表的键。不同之处在于计算了哪些列。还有,你 如果两个ID列的域不需要,则在上面的选项2中不需要TableName 重叠-只要您的case表达式可以确定哪个域
A\u或\u B\u ID
落入


(感谢评论修正了我的格式)

还有另一个选项。将
TableA
TableB
视为名为
TablePrime
的新表的子类。调整
表格B
的ID值,使其与
表格A
的ID值不一致。将
TablePrime
中的ID设置为PK,并将所有
TableA
TableB
的(调整)ID插入
TablePrime
。使
TableA
TableB
在其主键上具有与
TablePrime
中相同ID的FK关系

现在您有了超类型/子类型模式,并且可以对
TablePrime
(当您需要-A或-B)或其中一个单独的表(当您只需要A或B)进行约束


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

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

添加一个约束更容易,该约束引用一个用户定义的函数,该函数为您进行检查,fCheckIfValueExists(columnValue)如果值存在,则返回true;如果值不存在,则返回false

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

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

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

InnoDB是MySQL唯一一个内置的外键存储引擎。任何InnoDB表都将在信息_schema.tables中注册,引擎为'InnoDB'

视图在信息_schema.tables中注册时,具有空存储引擎。MySQL中没有在任何具有未定义存储引擎的表上具有外键的机制


谢谢

在后面加下划线:
A_或B_ID
我正在为一个遗留系统添加一些功能,这是一个很好的将新旧系统拼接在一起的方法。非常感谢。这是SQL server的一个限制还是一个不合理的需求?@Brian我也很想知道这是SQL server的一个限制还是一个不合理的需求,因为在这一点上,我将使用触发器模拟一个视图,以获得FK支持(尽管我使用的是MySql).这是对这些后续问题的一个很好的回答-我不确定这是对这些问题的一个很好的回答…这是关于一个不同的DBMS,并且说视图是为了隐藏模式细节和用户方便而设计的。首先,好吧……但这不是第一件在初始设计之外找到可靠用例的事情。其次,我不知道为什么一个FK不会这么做。一个视图可以是它甚至不必从表中提取的任何查询,它可以是一组联合在一起的常量……在这种情况下,外键似乎非常合理。如果有原因的话,我希望有更深层次的东西。欢迎来到StackOverflow。我发现你的答案很有价值,因为它提供了一个解决方法,但正确的答案是公认的,而且这个问题已经讨论了4年多了,所以我不会投票,但我不想不发表评论就离开。缺点是优化器不能使用他所有的外键技巧。。。并且该函数将针对插入/更新的每一行运行(所以对于集合来说不是太好)