如何在SQL Server中进行这种约束?

时间:2012-05-23 07:42:23

标签: sql sql-server constraints

假设有两张桌子,A和B. A包含字段:id,a1,a2。
B包含字段:id,b1,b2。

根据id字段设置从表A到B的一对多关系。

现在假设我想在表b上创建一个唯一约束,禁止我插入基于b1,b2和a1的重复记录。这可能吗?

2 个答案:

答案 0 :(得分:3)

您必须在a1中显示B的副本才能将此强制作为约束。如果您不希望用户看到这一点,您可以创建一个包含所有_B列+ B的表格(例如a1),然后创建一个视图(使用适当的插入触发器来填充a1名为B的隐藏此列的内容。

您还应创建A超过ida1的超级密钥,并使用来自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.