Mise à jour des loggings de database avec une contrainte unique

Étant donné la structure de table simple suivante (SQL Server 2008), je veux être en mesure de maintenir l'unicité de ma colonne de séquence numérique, mais je veux être en mesure de mettre à jour cette valeur pour un logging donné (s).

CREATE TABLE MYLIST( ID int NOT NULL IDENTITY(1, 1) , TITLE varchar(50) NOT NULL , SEQUENCE int NOT NULL , CONSTRAINT pk_mylist_id PRIMARY KEY(ID) , CONSTRAINT uq_mylist_sequence UNIQUE(SEQUENCE) ); 

Mon interface me permet de fausser l'ordre des items et je saurai avant de faire la mise à jour quelle séquence non chevauchante ils devraient tous être , mais comment effectuer la mise à jour sans être confronté à une violation de la contrainte unique?

Par exemple, dis que j'ai ces loggings:

 ID TITLE SEQUENCE 1 APPLE 1 2 BANANA 2 3 CHERRY 3 

Et je veux mettre à jour leurs numéros de séquence à ce qui suit:

 ID TITLE SEQUENCE 1 APPLE 3 2 BANANA 1 3 CHERRY 2 

Mais vraiment, je pourrais avoir affaire à quelques douzaines d'articles. Les numéros de séquence ne doivent pas se chevaucher. J'ai pensé à essayer d'utiliser des triggersurs ou de désactiver temporairement la contrainte, mais cela semblerait créer plus de problèmes. J'utilise C # et LINQ-to-SQL, mais je suis ouvert aux solutions ssortingctement de database.

Vous pouvez leur affecter le négatif de leur valeur correcte, puis après toutes les mises à jour, effectuez une mise à jour finale où vous définissez SEQUENCE = -SEQUENCE .

Ce n'est pas très efficace, mais puisque vous dites que vous n'avez que quelques douzaines d'articles, je doute que l'impact soit perceptible. Je suppose également que vous pouvez utiliser des nombres négatifs comme "valeurs magiques" pour indiquer temporairement des valeurs incorrectement assignées.

La manière évidente est d'écrire en un seul lot. En interne, SQL reportera les vérifications de contraintes de sorte que l'unicité intermédiaire n'est pas pertinente.

Écrire ligne par rangée n'a pas de sens et cause le problème que vous avez.

Vous pouvez changer cela pour écrire dans une table temporaire, puis "vider" les résultats à la fin, même vérifier l'unicité sur la table temporaire d'abord.

 DECLARE @NewSeq TABLE (ID int, NewSeq int) INSERT @NewSeq (ID, NewSeq) VALUES (1, 3) INSERT @NewSeq (ID, NewSeq) VALUES (2, 1) INSERT @NewSeq (ID, NewSeq) VALUES (3, 2) UPDATE M SET SEQUENCE = NewSeq FROM MYLIST M JOIN @NewSeq N ON M.ID = N.ID 

Si vous devez vraiment suivre ce workflow d'insertion sans connaître le bon ordre et ensuite devoir revenir avec une mise à jour plus tard pour définir le bon ordre, je dirais que votre meilleure option est de se débarrasser de la contrainte unique car elle cause vous plus de problèmes que cela en vaut la peine. Bien sûr, vous seul savez à quel point cette contrainte unique "vaut" pour votre application.