Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment échanger les valeurs de deux lignes dans MySQL sans violer la contrainte unique ?

Non. (aucun auquel je puisse penser).

Le problème est de savoir comment MySQL traite les mises à jour. MySQL (à la différence des autres SGBD qui implémentent UPDATE correctement), traite les mises à jour de manière interrompue. Il applique la vérification de UNIQUE (et autres) contraintes après chaque mise à jour de ligne et non - comme il se doit - après l'ensemble de la UPDATE déclaration se termine. C'est pourquoi vous n'avez pas ce problème avec (la plupart) des autres SGBD.

Pour certaines mises à jour (comme augmenter tout ou partie des identifiants, id=id+1 ), cela peut être résolu en utilisant - une autre fonctionnalité non standard - un ORDER BY dans la mise à jour.

Pour échanger les valeurs de deux lignes, cette astuce ne peut pas aider. Vous devrez utiliser NULL ou une valeur bidon (qui n'existe pas mais qui est autorisée dans votre colonne) et 2 ou 3 déclarations.

Vous pouvez également supprimer temporairement la contrainte unique, mais je ne pense pas que ce soit vraiment une bonne idée.

Ainsi, si la colonne unique est un entier signé et qu'il n'y a pas de valeurs négatives, vous pouvez utiliser 2 instructions enveloppées dans une transaction :

START TRANSACTION ;
    UPDATE tasks 
    SET priority = 
      CASE
        WHEN priority = 2 THEN -3 
        WHEN priority = 3 THEN -2 
      END 
    WHERE priority IN (2,3) ;

    UPDATE tasks 
    SET priority = - priority
    WHERE priority IN (-2,-3) ;
COMMIT ;