2010-05-17 6 views
4

Je suis en train de mettre en place une table qui sera utilisée pour envoyer des messages de suivi à certaines demandes d'information. Une demande est envoyée à un groupe de personnes et les réponses sont suivies. Si une personne ne répond pas, zéro ou plusieurs suivis peuvent être envoyés. J'ai créé une table:Désactiver les contraintes pendant la transaction

FollowupId int primary key, 
RequestId int foreign key (outside this example), 
Follows int foreign key (FollowupId), 
Message varchar 

Si un message doit être le premier message de suivi, Follows sera null. Sinon, c'est l'identifiant d'un autre suivi. J'ai également ajouté une contrainte unique sur Follows. Autrement dit, pas plus d'un message peut suivre un message donné.

EDIT: Je devrais également mettre en surbrillance la clé étrangère sur Suit. Il fait référence à FollowupId dans cette table. Donc, si A-> B-> C, la simple suppression de B rend la clé étrangère de C invalide. De même, il n'est pas possible de simplement mettre à jour C pour suivre A parce que B suit déjà A et que la contrainte unique interdit la duplication. Le problème est, bien sûr, que la suppression des entrées de suivi est maintenant difficile si ce message est suivi par un autre. Il me semble qu'il devrait être possible de désactiver la vérification des contraintes pour permettre de supprimer un suivi intermédiaire, "remonter" les suivis suivants, puis réactiver la vérification. Est-il possible de désactiver la contrainte uniquement pour la durée d'une transaction?

(De plus, je suis conscient de l'incohérence possible des données résultant de RequestId dans cette table Il peut être préférable d'avoir Followups [FollowupId, Message], InitialFollowups [FollowupId, RequestId] et FollowingFollowups [FollowupId, Suit Je pense que cela complique inutilement cet exemple.)

Répondre

3

activation/désactivation des contraintes de une modification est généralement une mauvaise idée, et la performance pourrait être nulle. À chaque fois que vous le faites, assurez-vous que votre contrainte n'est pas seulement activée mais qu'elle est approuvée une fois que vous avez terminé.

Dans votre cas, vous devez supprimer une ligne et en modifier une autre. Vous devriez utiliser MERGE si vous êtes déjà sur SQL 2008, ce qui vous permet à la fois de supprimer et de mettre à jour en une seule commande.

0

Mettez d'abord à jour vos autres valeurs, puis effectuez votre suppression.

Donc, si l'ordre est

A -> B -> C

et vous supprimez B, mise à jour C de Follows à A, la FollowedUp de A à C, puis supprimez B.

1

J'ai découvert que (au moins sur SQL Server), il n'est pas possible de désactiver les contraintes uniques. Il est possible de désactiver une contrainte de clé étrangère, de définir l'identifiant de l'enregistrement à supprimer comme identifiant invalide et impossible (comme -1 dans mon cas), de modifier les identifiants de suivi, de supprimer l'enregistrement en question, puis de reprendre la contrainte vérification. En supposant les données suivantes:

FollowId | RequestId | Suit | Message
1 | 17 | NULL | "Premier"
2 | 17 | 1 | "Deuxième, supprimez celui-ci"
3 | 17 | 3 | "Troisième, mais en font le deuxième"

J'utilisé la stratégie suivante:

// démarrer la transaction

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; 

// valider la transaction

Questions connexes