Sql server 具有条件的外键关系

Sql server 具有条件的外键关系,sql-server,constraints,relationship,Sql Server,Constraints,Relationship,早上好 我有一个带有ID和类型的主表。根据类型的不同,我有使用此ID作为外键的子表,以确保完整性。 例如,对于主表: master_ID, type 11, A 12, B 13, A 对于名为child_A的子表,它存储类型A的附加数据 Child_A_ID, FK_master_ID, .... 1, 11, .... 2, 13, .... 当子表中存在相应记录时,如何防止主表中的类型更改为其他值。我的引用完整性目前被保留,但在Child_中存储类型A的信息是没有意义的,而主表中的记录

早上好

我有一个带有ID和类型的主表。根据类型的不同,我有使用此ID作为外键的子表,以确保完整性。 例如,对于主表:

master_ID, type
11, A
12, B
13, A
对于名为child_A的子表,它存储类型A的附加数据

Child_A_ID, FK_master_ID, ....
1, 11, ....
2, 13, ....
当子表中存在相应记录时,如何防止主表中的类型更改为其他值。我的引用完整性目前被保留,但在Child_中存储类型A的信息是没有意义的,而主表中的记录是不同类型的

编辑:

唯一的解决方案是使用具有两个属性(ID和type)的外键并在每个子表中重复该类型吗? 给孩子一张桌子

Child_A_ID, FK_master_ID, type, ....
1, 11, A, ....
2, 13, A, ....
希望它足够清晰。

您可以创建一个使用来确定id值是否包含在相关类型表中的

ALTER TABLE MasterTable
  ADD CONSTRAINT CHK_MasterTable_Type
  CHECK(dbo.fn_check_IdBelongsToType(master_ID, type) = 1)
在函数本身中,您可以执行如下操作:

CREATE FUNCTION fn_check_IdBelongsToType (
    @master_ID int, 
    @type char(1)
)
RETURNS int
AS
BEGIN
   IF @Type = 'A' AND EXISTS (
       SELECT 1
       FROM Child_A
       WHERE FK_master_ID = @master_ID 
   ) RETURN 1

   IF @Type = 'B' AND EXISTS (
       SELECT 1
       FROM Child_B
       WHERE FK_master_ID = @master_ID 
   ) RETURN 1

   IF @Type = 'C' AND EXISTS (
       SELECT 1
       FROM Child_C
       WHERE FK_master_ID = @master_ID 
   ) RETURN 1

   -- after testing all child tables, return 0 to indicate that the value was not found
   RETURN 0

END

你能举个例子吗?您的意思是,如果主表中的ID已更改,而子表中仍有记录,该怎么办?@murtazat No主表中的ID将被保留,并且子表的完整性将得到维护。可能是更改了type属性导致了我的问题。即使您更改了主表中父键的数据类型,我认为子表的引用完整性将由数据库维护。那么,为什么要担心数据类型的变化呢?我不确定您的要求,但通常关注的是在子表中有孤立引用。是否需要在父表和子表中维护相同的数据类型?如果主id存在于任何子表中,则可以在主表上使用,但我不认为这是一种比使用多列外键更好的方法。@ZoharPeled Yes这将是一个很好的选择,因为我不想用type属性重载我的children表。有人能给我指出一个适合我的情况的约束示例吗?(dbo.fn\u check\u IdBelongsToType(master\u ID,type)=0)可能必须等于1