我正在整理一张表格,用于向某些信息请求发送跟进消息。将请求发送给一组人并跟踪响应。如果某人未能回复,则可能会发送零次或多次跟进。我创建了一个表:
FollowupId int primary key,
RequestId int foreign key (outside this example),
Follows int foreign key (FollowupId),
Message varchar
如果消息是第一个跟进消息,则Follows将为null。否则,它是其他一些Followup的id。我还在Follows上添加了一个独特的约束。也就是说,任何给定的消息都不能超过一条消息。
编辑:我还应该强调Follows上的外键。它引用了此表中的FollowupId。因此,如果A-> B-> C,则仅删除B使得C中的外键无效。同样,不可能只更新C以遵循A,因为B已经跟随A并且唯一约束禁止复制。当然,问题是如果该消息后面跟着另一个消息,则删除后续条目现在很困难。在我看来,应该可以禁用约束检查,以便可以删除中间跟进,“向上移动”后续跟进,然后重新启用检查。有没有办法在事务持续时间内禁用约束?
(另外,我知道在此表中使用RequestId可能会导致数据不一致。最好有Followups [FollowupId,Message],InitialFollowups [FollowupId,RequestId]和FollowFollowups [FollowupId,Follows]我认为这会让这个例子变得不必要。)
答案 0 :(得分:3)
禁用/启用某些修改的约束通常是一个坏主意,性能可能很糟糕。无论何时这样做,请确保您的约束不仅在启用后被启用,而且在您完成后也可以信任。
在您的情况下,您需要删除一行并修改另一行。如果您已经在SQL 2008上,则应该使用MERGE,这允许您在一个命令中删除和更新。
答案 1 :(得分:1)
我发现(至少在SQL Server上)不可能禁用唯一约束。可以禁用外键约束,将要删除的记录的id设置为无效且不可能的id(例如我的情况下为-1),更改后续ID,删除有问题的记录,然后恢复约束检查。假设以下数据:
FollowId | RequestId |关注|消息
1 | 17 | NULL | “第一个”
2 | 17 | 1 | “第二个,删除这一个”
3 | 17 | 3 | “第三个,但让它成为第二个”
我使用了以下策略:
//启动交易
alter table RequestFollowups NOCHECK CONSTRAINT FK_Follows_FollowId;
update RequestFollowups set Follows=-1 where FollowupId=2;
update RequestFollowUps set Follows=1 where FollowupId=3;
delete from RequestFollowups where FollowupId=2;
alter table RequestFollowups WITH CHECK CHECK CONSTRAINT FK_Follows_FollowId;
//提交交易
答案 2 :(得分:0)
首先更新您的其他值,然后执行删除。
所以,如果订单是
A - > B - > ç
你要删除B,将C的跟随A更新,A跟随C更新,然后删除B.