1

我有 2 张桌子

Table A
Column A1 Column A2 and

Table B
Column B1 Column B2

A1 列不是唯一的,也不是 PK,但我想对 B1 列施加一个约束,即它不能具有除 A1 列中的值以外的值,可以做到吗?

4

4 回答 4

1

使用 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
于 2013-07-26T13:56:17.550 回答
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) 

另外,我会添加它是一种非常设计的做法,并且不能一直保证准确性。

于 2013-07-26T14:10:58.570 回答
0

很长的路要走,但您可以向 A 添加一个身份并将 PK 声明为 iden,A1。
在 B iden 中只是一个整数(不是身份)。
您要求任何其他方式。

可以创建第三个表,该表是两者都使用的 FK,但不能确保 B1 在 A 中。

于 2013-07-26T14:18:29.917 回答
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

现在我们可以使用真正的外键 from TableBto UniqueAs。这应该都是相对有效的——通常的 FK 机制在TableB和之间可用UniqueAs,并且这个表的维护总是通过 PK 引用——我们不必不必要地重新扫描TableA——我们只使用触发器伪表。

于 2013-07-26T14:29:18.510 回答