外键中某些列的条件

时间:2015-02-04 12:52:54

标签: sql sql-server tsql foreign-keys constraints

表A包含列(Id,BId)。 BId是表B的外键.B具有列(Id,Type)。

CREATE TABLE [A] (
    [Id] INT IDENTITY CONSTRAINT [PK_A_Id] PRIMARY KEY,
    [BId] INT NOT NULL CONSTRAINT [FK_A_B] REFERENCES [B](Id) 
)
GO
CREATE TABLE [B] (
    [Id] INT IDENTITY CONSTRAINT [PK_B_Id] PRIMARY KEY,
    [Type] INT NOT NULL 
)
GO

所以,这是一个非常简单的方案,但我想为外键增加条件,比如“type should be 0”。它应该像

CONSTRAINT [FK_A_B] REFERENCES [B](Id) WHERE [B].[Type] = 0

如何正确使用UNIQUE关键字或其他方法来实现它?

2 个答案:

答案 0 :(得分:0)

如果可以使用过滤的唯一索引来完成这将是很好的。但是,SQL Server不允许这样做。所以这是另一个想法:

首先在:

上定义(冗余)唯一约束
CREATE TABLE [B] (
    [Id] INT IDENTITY CONSTRAINT [PK_B_Id] PRIMARY KEY,
    [Type] INT NOT NULL,
    UNIQUE (ID, Type)
)
GO

现在,我不认为您可以将约束定义为:

CONSTRAINT [FK_A_B] (ID, 0) REFERENCES [B](Id, Type) 

但是,我认为你可以通过这样做来欺骗它:

_Type as 0,
CONSTRAINT [FK_A_B] (ID, _Type) REFERENCES [B](Id, Type) 

即,添加计算列并将其用于约束。

答案 1 :(得分:0)

您要实现的目标不是FOREIGN KEY的任务。在FK中,您无法在目标表上指定其他条件。如果您有这种需要,通常意味着您的数据库没有标准化。看起来table [B]在一个表中存储了几个数据实体,而Type列确定了它是什么实体。如果您违反了规范化规则,声明性完整性意味着像FK不适合您。从现在开始,你必须自己控制完整性。您可以在应用程序逻辑中执行此操作或创建触发器(过程完整性)。在任何情况下,DB中都没有外键约束。