我有 2 张桌子
Table A
Column A1 Column A2 and
Table B
Column B1 Column B2
A1 列不是唯一的,也不是 PK,但我想对 B1 列施加一个约束,即它不能具有除 A1 列中的值以外的值,可以做到吗?
我有 2 张桌子
Table A
Column A1 Column A2 and
Table B
Column B1 Column B2
A1 列不是唯一的,也不是 PK,但我想对 B1 列施加一个约束,即它不能具有除 A1 列中的值以外的值,可以做到吗?
使用 FK 无法做到这一点。相反,您可以使用检查约束来查看 B 值是否在 A 中可用。
例子:
alter table TableB add constraint CK_BValueCheck check dbo.fn_ValidateBValue(B1) = 1
create function dbo.fn_ValidateBValue(B1 int)
returns bit as
begin
declare @ValueExists bit
select @ValueExists = 0
if exists (select 1 from TableA where A1 = B1)
select @ValueExists = 1
return @ValueExists
end
您不能有动态约束来限制表 B 中的值。相反,您可以在 TableB 上触发,或者您需要限制 TbaleB 上的所有插入或更新以仅从 A 列中选择值:
Insert into TableB
Select Col from Table where Col in(Select ColumnA from TableA)
或者
Update TableB
Set ColumnB= <somevalue>
where <somevalue> in(Select columnA from TableA)
另外,我会添加它是一种非常设计的做法,并且不能一直保证准确性。
很长的路要走,但您可以向 A 添加一个身份并将 PK 声明为 iden,A1。
在 B iden 中只是一个整数(不是身份)。
您要求任何其他方式。
可以创建第三个表,该表是两者都使用的 FK,但不能确保 B1 在 A 中。
如果我可以自由地在数据库中创建表和触发器,并且仍然希望TableA
允许多个A1
值,这就是我要采用的设计。我要介绍一个新表:
create table TableA (ID int not null,A1 int not null)
go
create table UniqueAs (
A1 int not null primary key,
Cnt int not null
)
go
create trigger T_TableA_MaintainAs
on TableA
after insert, update, delete
as
set nocount on
;With UniqueCounts as (
select A1,COUNT(*) as Cnt from inserted group by A1
union all
select A1,COUNT(*) * -1 from deleted group by A1
), CombinedCounts as (
select A1,SUM(Cnt) as Cnt from UniqueCounts group by A1
)
merge into UniqueAs a
using CombinedCounts cc
on
a.A1 = cc.A1
when matched and a.Cnt = -cc.Cnt then delete
when matched then update set Cnt = a.Cnt + cc.Cnt
when not matched then insert (A1,Cnt) values (cc.A1,cc.Cnt);
并测试一下:
insert into TableA (ID,A1) values (1,1),(2,1),(3,2)
go
update TableA set A1 = 2 where ID = 1
go
delete from TableA where ID = 2
go
select * from UniqueAs
结果:
A1 Cnt
----------- -----------
2 2
现在我们可以使用真正的外键 from TableB
to UniqueAs
。这应该都是相对有效的——通常的 FK 机制在TableB
和之间可用UniqueAs
,并且这个表的维护总是通过 PK 引用——我们不必不必要地重新扫描TableA
——我们只使用触发器伪表。