我正在整理一个表,该表将用于向某些信息请求发送跟进消息。请求将发送给一组人,并跟踪响应。如果某个人未响应,则可能会发送零个或多个跟进消息。我创建了一个表:
FollowupId int primary key,
RequestId int foreign key (outside this example),
Follows int foreign key (FollowupId),
Message varchar
如果一条消息是第一条后续消息,Follows将为null,否则,它是其他一些后续消息的id,我还在Follows上添加了一个唯一的约束,也就是说,不能有一条以上的消息跟随任何给定的消息。
编辑:我还应该突出显示Follows上的外键。它引用了这个表中的FollowupId。因此,如果A-〉B-〉C,仅仅删除B就会使C中的外键无效。类似地,仅仅更新C以跟随A是不可能的,因为B已经跟随A,并且唯一约束禁止复制。
当然,问题是,如果该消息后面跟着另一个消息,则删除后续条目现在很困难。在我看来,应该可以禁用约束检查,以便可以删除中间的后续消息,“上移”后续的后续消息,然后重新启用检查。是否有某种方法可以仅在事务的持续时间禁用约束?
(Also,我意识到在这个表中使用RequestId可能会导致数据不一致。使用Followups [FollowupId,Message]、InitialFollowups [FollowupId,RequestId]和FollowingFollowups [FollowupId,Follows]表可能会更好。不过我认为这不必要地使这个示例复杂化。)
3条答案
按热度按时间dbf7pr2w1#
为某些修改禁用/启用约束通常不是一个好主意,而且性能可能会很差。无论何时执行此操作,请确保您的约束不仅是启用的,而且在完成后是受信任的。
在您的情况下,您需要删除一行并修改另一行。如果您已经使用SQL 2008,则应该使用MERGE,这样可以在一个命令中同时执行删除和更新操作。
qaxu7uf22#
我发现(至少在SQL Server上)禁用唯一约束是不可能的。可以禁用外键约束,将要删除的记录的id设置为无效和不可能的id(例如在我的例子中为-1),更改跟踪id,删除有问题的记录,然后恢复约束检查。假设以下数据:
我使用了以下策略:
(Note倒数第二行is intentional and not a typo上的
CHECK CHECK
。)kdfy810k3#
首先更新其他值,然后执行删除操作。
所以如果顺序是
A → B → C
你要删除B,更新C的Follows到A,A的FollowedUp到C,然后删除B。