假设有两个表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中创建这种约束?
从表A到表B根据id字段从一个到多个关系展开。
现在我们假设我想在表b上创建一个唯一约束,禁止我插入基于b1,b2和a1的重复记录。那可能吗?
假设有两个表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中创建这种约束?
从表A到表B根据id字段从一个到多个关系展开。
现在我们假设我想在表b上创建一个唯一约束,禁止我插入基于b1,b2和a1的重复记录。那可能吗?
您必须拥有a1
副本才能出现在B
中,以强制执行此操作为约束。如果您不希望对用户可见,请创建一个包含所有B
s列+ a1
的表格(例如_B
),然后创建一个名为B
的视图(具有合适的插入触发器以填充a1
),该视图隐藏本专栏。
您还应该创建一个A
在超密钥和id
a1
,并使用外键约束(可能与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
一种解决方案可能是创建表A重复值的函数测试并添加检查约束的功能,引用表B.
+1 。是否需要'约束FK_B_A'(在添加'DRI_B_A_a1_check'之后)? –
看到第三段 - 正如我所说,这是一个品味问题。它“记录”了真实的关系(尽管'DRI_'有足够的希望能够向下一个人提供线索,表明它是为了DRI目的而不是作为真正的外键) –
听起来就像在表B中添加a1一样那么对我而言,这将是一个更简单的解决方案。值得庆幸的是,这是一个永不改变的价值,所以我应该能够做到这一点,而不用担心标题和细节表进入不一致的状态。 –