使用存储过程在SQL Server中进行软删除

时间:2014-11-15 21:40:57

标签: sql sql-server sql-server-2008

我有3个表tblteamtblaccounttbluser,其中包含以下列:

tblTeam

(TeamId int,
 TeamName varchar(20),
 IsDeleted bit)

tblUser

(UserId int,
 UserName varchar(20),
 TeamId int)

tblAccount

(AccountId int,
 AccountName varchar(20),
 TeamId int,
 UserId int
)

我想要做的是我想用1更新已删除的列。

为此我试过

Create procedure sp_isdeleted(
     @pteamid int
As 
Begin
     Update tblTeam 
     set IsDeleted = 1 
     Where TeamId = @pteamid
End

但我想要的是,如果团队与任何用户或帐户相关联,并且团队中剩余的任何用户Isdeleted仍为0。

我该如何检查这种情况?请帮忙。

2 个答案:

答案 0 :(得分:2)

在SP中尝试此更新语句:

Update t 
set t.IsDeleted = 1 
from tblTeam t
where t.TeamId = @pteamid 
and not exists (select 1 from tblUser where TeamId = @pteamid)
and not exists (select 1 from tblAcount where TeamId = @pteamid)

答案 1 :(得分:1)

如果将逻辑放在一个地方或许多地方,仍有可能从其他地方执行软删除。您希望无法随时随地进行删除。如果系统会强制执行默认的FK限制(如果有任何FK引用它就不能删除行),软删除就像硬删除一样,这不是很好吗?说,有个主意!实施起来非常简单。

只需将删除标志作为表的PK的一部分(或者更好,只需将PK与PK一起添加到唯一索引)。然后每个FK到Team在该字段中使用0值。如果有任何FK引用该团队,将阻止任何修改IsDeleted字段的尝试。

这是来自内存所以语法可能是iffy:

create table Teams(
    ID        int not null,
    IsDeleted bit not null default 0,
    ...
    constraint PK_Teams primary key( ID )
);
create unique index UQ_Team_ID_IsDeleted on Team( ID, IsDeleted );

create table AllOthers(
    ...
    TeamID         int,
    TeamStillThere bit,
    ...
    constraint CK_TeamStillThere check IsNull( TeamStillThere, 0 ) = 0;
    constraint FK_AllOthers_Teams foreign key( TeamID, TeamStillThere )
        references Teams( ID, IsDeleted );
);

请注意,FK只能引用未删除的团队,并且一旦建立连接,就无法删除团队(硬或软)。此外,如果该引用不关心团队是否被删除,您仍然可以定义仅对PK的FK引用 - 例如,团队的历史记录。无论哪种方式,让系统尽可能地完成所有工作。