12

我想在表中定义两个可为空的 FK 之间的约束,如果一个为空,则另一个需要一个值,但两者都不能为空,并且两者都不能有值。逻辑是派生表从任一 FK 表中继承数据以确定其类型。另外,为了有趣的奖励积分,这是一个坏主意吗?

4

3 回答 3

19

实现它的一种方法是简单地写下“异或”的实际含义:

CHECK (
    (FK1 IS NOT NULL AND FK2 IS NULL)
    OR (FK1 IS NULL AND FK2 IS NOT NULL)
)

但是,如果您有很多 FK,上述方法很快就会变得笨拙,在这种情况下,您可以执行以下操作:

CHECK (
    1 = (
        (CASE WHEN FK1 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK2 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK3 IS NULL THEN 0 ELSE 1 END)
        + (CASE WHEN FK4 IS NULL THEN 0 ELSE 1 END)
        ...
    )
)

顺便说一句,该模式有合法用途,例如这个(尽管由于缺乏延迟约束而不适用于 MS SQL Server)。在您的特定情况下是否合法,我无法根据您迄今为止提供的信息来判断。

于 2012-06-20T20:34:58.850 回答
1

您可以使用检查约束

create table #t (
   a int,
   b int);

alter table #t add constraint c1 
check ( coalesce(a, b) is not null and a*b is null );

insert into #t values ( 1,null);

insert into #t values ( null ,null);

跑步:

The INSERT statement conflicted with the CHECK constraint "c1". 
于 2012-06-20T20:15:02.887 回答
-1

另一种方法是在过程中定义此检查约束。在派生表中插入记录之前,应满足约束条件。否则插入失败或返回错误。

于 2012-06-20T20:26:30.293 回答