您可以使用一些计算列来做到这一点,但它看起来不是很漂亮:
CREATE TABLE A (
A_UNIQUE_ID int NOT NULL PRIMARY KEY,
A_OTHER_ID int NOT NULL,
A_CURRENT_FL bit NOT NULL,
OTHER_XREF as CASE WHEN A_CURRENT_FL = 1 THEN A_OTHER_ID END persisted,
UNIQ as CASE WHEN A_CURRENT_FL = 0 THEN A_UNIQUE_ID ELSE 0 END persisted
constraint UQ_OTHER_XREF UNIQUE (OTHER_XREF,UNIQ)
)
INSERT INTO A VALUES (1, 1, 0);
INSERT INTO A VALUES (2, 1, 0);
INSERT INTO A VALUES (3, 1, 1);
CREATE TABLE B (
B_UNIQUE_ID int NOT NULL PRIMARY KEY,
A_OTHER_ID int NOT NULL,
XREF as 0 persisted,
constraint FK_B_A FOREIGN KEY (A_OTHER_ID,XREF) references A (OTHER_XREF,UNIQ))
这有效:
insert into B VALUES (2,1)
这打破了 FK 约束:
insert into B VALUES (3,2)
表 A 中的两个计算列确保任何带有A_CURRENT_FL
=1
的行在OTHER_XREF
. 其他行将NULL
在该列中。然而,为了应用一个UNIQUE
约束(外键的目标),我们需要一个对于带有 a 的每一行都明显不同的东西,同时对于带有=NULL
的行来说是一个众所周知的值。在这种情况下,我制作了众所周知的 value 。A_CURRENT_FL
1
0
最后,外键约束需要匹配这两个列,所以我们在表 B 中添加一个新的计算列,该列具有众所周知的值0
。
列名不是特别好,但我相信你能想出一些。
Note, also, that by the above, we've also implemented another constraint that you didn't mention, but that also may be important - there can't be two rows now in table A that both have A_CURRENT_FL
set to 1, for the same A_OTHER_ID
value. This also generates an error:
INSERT INTO A VALUES (4,1,1);