假设有两张桌子,A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。
根据id字段设置从表A到B的一对多关系。
现在假设我想在表b上创建一个唯一约束,禁止我插入基于b1,b2和a1的重复记录。这可能吗?
答案 0 :(得分:3)
您必须在a1
中显示B
的副本才能将此强制作为约束。如果您不希望用户看到这一点,您可以创建一个包含所有_B
列+ B
的表格(例如a1
),然后创建一个视图(使用适当的插入触发器来填充a1
名为B
的隐藏此列的内容。
您还应创建A
超过id
和a1
的超级密钥,并使用来自ON UPDATE CASCADE
的外键约束(可能包含B
)这两个列都可以确保此复制的列与A
中的相应值正确匹配。
你是否决定这应该是唯一的外键,或者继续维持“正确的”外键(仅仅id
),这是一个品味问题。
E.g:
CREATE TABLE dbo.A (ID int not null,a1 int not null,a2 int not null,
constraint PK_A PRIMARY KEY (id),
constraint UQ_A_a1_check UNIQUE (id,a1)
)
CREATE TABLE dbo._B (ID int not null,a1 int not null,b1 int not null,b2 int not null,
constraint PK_B PRIMARY KEY (a1,b1,b2),
constraint FK_B_A FOREIGN KEY (id) references A (id),
constraint DRI_B_A_a1_check FOREIGN KEY (id,a1) references A (id,a1) on update cascade
)
GO
CREATE VIEW dbo.B
WITH SCHEMABINDING
AS
select id,b1,b2 from dbo._B
GO
CREATE TRIGGER T_B_I on dbo.B instead of insert
AS
INSERT INTO dbo._B (id,a1,b1,b2)
SELECT i.id,a.a1,i.b1,i.b2
FROM
inserted i
inner join
dbo.A a
on
i.id = a.id
GO
答案 1 :(得分:0)
一种解决方案可能是为表A中的重复值创建函数测试,并添加一个Check约束,该约束将函数引用到表B.