4

Étant donné la structure de tableau simple suivante (SQL Server 2008), je souhaite pouvoir conserver l'unicité de ma colonne de séquence numérique, mais je souhaite pouvoir mettre à jour cette valeur pour un enregistrement donné (s).Mise à jour des enregistrements de base de données avec contrainte unique

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 pêle-mêle l'ordre des articles et je saurai avant de faire la mise à jour qui séquence non-chevauchement ils devraient tous être en, mais comment puis-je effectuer la mise à jour sans confronté à une violation de la contrainte unique?

Par exemple, dire que j'ai ces documents:

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 à un des éléments de couple douzaine . Les numéros de séquence ne doivent pas se chevaucher. J'ai pensé à essayer d'utiliser des déclencheurs 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 strictement de base de données.

+0

Pouvez-vous mettre à jour dans une déclaration? – gbn

+0

J'ai la liberté d'essayer à peu près n'importe quoi si cela répond à votre question. – JustinStolle

Répondre

2

Vous pouvez les assigner la négative de leur valeur correcte, puis après toutes les mises à jour ont eu lieu, faire une mise à jour finale où vous définissez SEQUENCE = -SEQUENCE.

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

+0

J'aime la simplicité de cela et en fait pensé moi-même quelques minutes après avoir posté la question. Pour ma situation, cela peut sembler le plus logique. – JustinStolle

+0

Hmmm ... rien n'empêche quelqu'un d'entrer un nombre négatif directement dans la base de données, ce qui casserait cette solution. –

3

La méthode la plus simple consiste à é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 ligne n'a pas de sens et cause le problème que vous avez.

Vous pouvez modifier cela pour écrire dans une table temporaire, puis "vider" les résultats à la fin, vérifiez même l'unicité sur la table temporaire en premier.

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 
+0

Cela semble être la solution techniquement correcte avec le moins de chance d'erreur, bien que cela nécessiterait du code supplémentaire. Pour mes fins, l'astuce numérique de Dave est suffisante. – JustinStolle

0

Si vous devez vraiment suivre ce workflow d'insertion sans connaître le bon ordre et devoir ensuite 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 parce que cela vous cause 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.

+0

Je connais l'ordre correct/désiré à l'avance avant la mise à jour. – JustinStolle

+0

Droit mais vous ne connaissez pas l'ordre correct avant l'insertion, non? –

+0

Je connaîtrais à la fois la séquence actuelle et la nouvelle séquence désirée pour tous les enregistrements.Je me renseigner seulement sur les mises à jour et non sur les insertions. Mais je suis curieux, votre interprétation des contraintes uniques que leurs valeurs ne peuvent être écrites qu'une seule fois et n'a jamais changé? – JustinStolle

Questions connexes