不允许除其他表中的列值之外的列值

时间:2013-07-26 13:42:06

标签: sql-server tsql constraints foreign-key-relationship

我有2张桌子

Table A
Column A1 Column A2 and

Table B
Column B1 Column B2

列A1不是唯一的而不是PK,但我想在列B1上设置一个约束,它不能具有除A1列中的值之外的值,是否可以完成?

4 个答案:

答案 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

现在我们可以使用从TableBUniqueAs的真正外键。这应该都是相对有效的 - 通常的FK机制在TableBUniqueAs之间可用,并且该表的维护总是通过PK引用 - 我们不必不必要地重新扫描所有{ {1}} - 我们只使用触发器伪表。