既然要执行软删除,你可以完成你想要的东西通过添加一些额外的辅助列和外键:
create table Books (
Id uniqueidentifier primary key,
Title varchar(255) not null,
Author varchar(255) not null,
Deleted datetime null,
_DelXRef as CASE WHEN Deleted is null then 0 else 1 END persisted,
constraint UQ_Books_DelXRef UNIQUE (Id,_DelXRef)
)
create table Categories (
Id uniqueidentifier primary key,
Name varchar(255) not null,
Deleted datetime null,
_DelXRef as CASE WHEN Deleted is null then 0 else 1 END persisted,
constraint UQ_Categories_DelXRef UNIQUE (Id,_DelXRef)
)
create table BookCategories (
BookId uniqueidentifier not null,
CategoryId uniqueidentifier not null,
_DelXRef as 0 persisted,
constraint FK_BookCategories_Books foreign key (BookID) references Books(Id),
constraint FK_BookCategories_Books_DelXRef foreign key (BookID,_DelXRef) references Books(Id,_DelXRef),
constraint FK_BookCategories_Categories foreign key (CategoryId) references Categories(Id),
constraint FK_BookCategories_Categories_DelXRef foreign key (CategoryId,_DelXRef) references Categories(Id,_DelXRef)
)
希望,你可以看到外键如何确保引用表中的_DelXRef
列始终保持0
,因此无法将Deleted
设置为任何非NULL值,同时从BookCategories
表中引用该行。 (现在,“原始”外键,FK_BookCategories_Books
和FK_BookCategories_Categories
似乎是多余的。我更喜欢让他们在模型中记录真正的FK关系。我也使用我自己的约定前缀对象与_
其中,它并不意味着他们可以使用到数据库的用户 - 他们只是存在,使DRI予以强制执行)
“当我删除的项目,我不真正删除它们,但设置属性删除,约会时间。”那么你将不得不使用'UPDATE'触发器;限制不会帮助你。 –
更新触发器是什么意思? @JeroenMostert – aiden87
我会加我5美分。@JeroenMostert的意思是你不是在物理上删除记录,所以外键(人们建议你使用)不会以这种方式提供帮助,唯一可以实现的方式是使用TRIGGER而不是CONSTRAINT。在那里你需要实现检查是否有任何使用它的记录的逻辑。 –