表约束启用部分记录

时间:2018-09-16 14:09:02

标签: sql sql-server database foreign-keys constraints

我有一个数据库,并且有两个表employees和cards。员工表中有一个主键EmplID,而卡表中是一个外键。新功能要求将记录(临时卡)添加到具有伪造(随机生成)EmplID的Cards表中,而EmplID在Employees表中不存在。我需要替换Cards表中的外键,这将适用于表中的部分记录。

1 个答案:

答案 0 :(得分:1)

我完全同意SMor的观点,这样做可能是一个非常糟糕的主意。您应该重新考虑您的要求以及您要实现的目标。

最简单的解决方案是将带有伪ID的记录添加到Employee表中,以便保持约束。

话虽这么说,可能吗?是的,……有点,……有点。

首先,您需要能够区分不需要约束的伪记录和需要约束的真实记录。在我的示例中,我添加了一个布尔标志IsFake,但是您的条件可能有所不同。

然后创建一个计算列,如果它是真实记录,则保存EmpID,如果它是假记录,则保存NULL,并针对该列设置外键约束。请注意,为了在计算列上强制使用外键约束,必须对其进行持久化

create table Emp ( EmpID int not null primary key identity(1,1), 
                   EmpName nvarchar(60) )

create table Crd ( CrdID int not null primary key identity(1,1),
                   IsFake bit not null,
                   MaybeEmpID int,
                   CrdVal nvarchar(60),

                   EmpID as 
                     case when IsFake=1 then NULL else MaybeEMPID end 
                     persisted 
                     foreign key references Emp(EmpID)
                   )

-- Create some real records
declare @ID int

insert into Emp ( EmpName ) values ( 'Fred' )
set @ID = scope_identity()
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 0, @ID, 'King' )
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 0, @ID, 'Jack' )

insert into Emp ( EmpName ) values ( 'Mary' )
set @ID = scope_identity()
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 0, @ID, 'Queen' )
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 0, @ID, 'Ace'   )

-- Create some fake records
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 1, 9876789, 'Five'  )
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 1, 9876789, 'Three' )
insert into Crd ( IsFake, MaybeEmpID, CrdVal ) values ( 1, 7474747, 'Seven' )

select * from Emp

select * from Crd

select * from Emp,Crd where Emp.EmpID = Crd.EmpID