4 votes

Mise à jour de plusieurs lignes qui sont en conflit avec l'index unique.

J'utilise Microsoft SQL Server et j'ai un scénario maître-détail dans lequel je dois stocker l'ordre des détails. Ainsi, dans la table Détail, j'ai ID, MasterID, Position et quelques autres colonnes. Il y a également un index unique sur MasterID et Position. Tout fonctionne bien, sauf dans un cas : lorsque j'ai des détails existants et que je change leur ordre. Par exemple, lorsque je change un détail sur la position 3 avec un détail sur la position 2. Lorsque je sauvegarde le détail sur la position 2 (qui dans la base de données a une position égale à 3) le serveur SQL proteste, parce que la contrainte d'unicité de l'index.

Comment résoudre ce problème de manière raisonnable ?

Merci d'avance
Lukasz Glaz

2voto

Mark Brittingham Points 18970

C'est un problème classique et la réponse est simple : si vous voulez déplacer l'élément 3 en position 2, vous devez d'abord changer la colonne de tri de 2 en un nombre temporaire (par exemple 99). Cela se passe donc comme suit :

Move 2 to 99
Move 3 to 2
Move 99 to 3

Vous devez toutefois veiller à ce que votre valeur temporaire ne soit jamais utilisée dans le cadre d'un traitement normal et à ce que vous respectiez plusieurs threads le cas échéant.

Mise à jour : BTW - une façon de traiter le problème "plusieurs utilisateurs peuvent modifier l'ordre" est de faire ce que je fais : donner à chaque utilisateur un ID numérique et l'ajouter ensuite au numéro temporaire (mon ID personnel est en fait l'ID du champ Identité unique de la table du personnel utilisée pour contrôler les connexions). Ainsi, par exemple, si vos positions ne seront jamais négatives, vous pouvez utiliser -1000 - ID utilisateur comme valeur temporaire. Faites-moi confiance sur un point : vous devez no vous ne voulez pas partir du principe que vous n'aurez jamais de collision. Si vous pensez cela et qu'une hace se produire, il sera extrêmement difficile de déboguer !

Mise à jour : GUZ souligne que ses utilisateurs peuvent avoir réorganisé un ensemble complet de postes et les avoir soumis en tant que lot - il ne s'agit pas simplement d'un changement de deux enregistrements. Vous pouvez donc aborder ce problème de deux façons.

Tout d'abord, vous pourriez modifier les champs de tri existants de l'ensemble du jeu en un nouvel ensemble de valeurs non concordantes (par exemple -100 - (staffID * maxSetSize) + existingOrderVal), puis procéder enregistrement par enregistrement et modifier chaque enregistrement en fonction de la nouvelle valeur de commande.

Ou vous pourriez essentiellement le traiter comme un tri à bulles sur un tableau où la valeur orderVal est l'équivalent de l'index de votre tableau. Soit cette solution est parfaitement logique pour vous (et évidente), soit vous devriez vous en tenir à la solution 1 (qui est de toute façon plus simple).

0voto

oedo Points 5438

Vous pourriez simplement supprimer la contrainte unique (mais laisser une clé d'index) sur la colonne order, et assurer l'unicité dans votre code si nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X