我有2张桌子
Table A
Column A1 Column A2 and
Table B
Column B1 Column B2
列A1不是唯一的而不是PK,但我想在列B1上设置一个约束,它不能具有除A1列中的值之外的值,是否可以完成?
答案 0 :(得分:1)
使用FK无法完成。相反,您可以使用检查约束来查看A值中是否有B值。
示例:
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
答案 1 :(得分:0)
您不能使用动态约束来限制表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)
另外,我会添加一个非常设计的做法,并不能一直保证准确性。
答案 2 :(得分:0)
很长的路要走但你可以为A添加一个身份并将PK声明为iden,A1 在B中,iden只是一个整数(不是同一性) 你问过其他任何方式。
可以创建第三个表,它是两者都使用的FK,但不能保证B1在A中。
答案 3 :(得分:0)
如果我可以在数据库中自由创建表和触发器,并且仍然希望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
现在我们可以使用从TableB
到UniqueAs
的真正外键。这应该都是相对有效的 - 通常的FK机制在TableB
和UniqueAs
之间可用,并且该表的维护总是通过PK引用 - 我们不必不必要地重新扫描所有{ {1}} - 我们只使用触发器伪表。