2012-05-23 46 views
1

假设有两个表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中创建这种约束?

从表A到表B根据id字段从一个到多个关系展开。

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

回答

3

您必须拥有a1副本才能出现在B中,以强制执行此操作为约束。如果您不希望对用户可见,请创建一个包含所有B s列+ a1的表格(例如_B),然后创建一个名为B的视图(具有合适的插入触发器以填充a1),该视图隐藏本专栏。

您还应该创建一个A在超密钥和ida1,并使用外键约束(可能与ON UPDATE CASCADE)从B在这两列,以确保这个复制列正确匹配A相应的值。

不管你是否决定这应该是唯一的外键,还是继续保持“正确”的一个(仅仅是id)另外是一个口味问题。


如:

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 
+0

+1 。是否需要'约束FK_B_A'(在添加'DRI_B_A_a1_check'之后)? –

+0

看到第三段 - 正如我所说,这是一个品味问题。它“记录”了真实的关系(尽管'DRI_'有足够的希望能够向下一个人提供线索,表明它是为了DRI目的而不是作为真正的外键) –

+0

听起来就像在表B中添加a1一样那么对我而言,这将是一个更简单的解决方案。值得庆幸的是,这是一个永不改变的价值,所以我应该能够做到这一点,而不用担心标题和细节表进入不一致的状态。 –

0

一种解决方案可能是创建表A重复值的函数测试并添加检查约束的功能,引用表B.