From the relational point of view, your PKs are not valid, because there is a subset of it which is a valid PK itself (the Id
column). It will also allow to have two rows with the same Id, but one deleted and one not (which I presume is not what you're after). If you really want to go this way, I'd make a PK on just the Id
column, and perhaps a unique on Id, IsDeleted
. Your FK can reference any unique key, not just PK.
Furtheron, use on update cascade
option when declaring a FK, it will take care of updating the ParentIsDeleted
column, and then you'll need a trigger to propagate to 'IsDeleted'. See the code:
create table Parent
(
Id int not null,
IsDeleted bit not null,
)
alter table Parent add constraint PPK primary key (Id)
alter table Parent add constraint uq unique (Id, IsDeleted)
create table Child
(
Id int not null,
IsDeleted bit not null,
ParentId int not null,
ParentIsDeleted bit not null,
)
alter table Child add constraint CPK primary key (Id, IsDeleted)
alter table Child add constraint CFK foreign key (ParentId, ParentIsDeleted) references Parent(Id, IsDeleted) on update cascade
go
create trigger trChildUpdate
on Child
after update
as
select trigger_nestlevel(object_id('trChildUpdate'), 'AFTER', 'DML');
if ((select trigger_nestlevel(object_id('trChildUpdate'), 'AFTER', 'DML')) > 1)
return;
update c
set c.IsDeleted = i.ParentIsDeleted
from Child c inner join Inserted i on c.Id = i.Id
go
insert into Parent values(100,0)
insert into Child values(1000,0,100,0)
update Parent set IsDeleted = 1
select * from child