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 ;