est-il possible d'échanger des valeurs de clé primaire entre deux ensembles de données? Si oui, comment ferait-on cela?sql swap valeurs de clé primaire
Répondre
Soit ce par souci de simplicité suppose que vous avez deux enregistrements
id name
---------
1 john
id name
---------
2 jim
à la fois de la table t (mais ils peuvent provenir de différentes tables)
Vous pouvez faire
UPDATE t, t as t2
SET t.id = t2.id, t2.id = t.id
WHERE t.id = 1 AND t2.id = 2
Remarque : La mise à jour des clés primaires a d'autres effets secondaires et peut-être que l'approche préférée consisterait à laisser les clés primaires telles quelles et à inverser les valeurs de toutes les clés. Les autres colonnes
Avertissement: La raison pour laquelle le t.id = t2.id, t2.id = t.id
fonctionne est que, dans SQL, la mise à jour se produit au niveau d'une transaction. Le t.id
n'est pas variable et =
n'est pas affecté. Vous pourriez l'interpréter comme "mettre t.id à la valeur t2.id avant l'effet de la requête, mettre t2.id à la valeur t.id avant l'effet de la requête". Cependant, certaines bases de données peuvent ne pas être correctement isolées, voir par exemple question (cependant, exécuter la requête ci-dessus, qui est probablement considérée comme une mise à jour multi-tables, se comporte selon la norme dans mysql).
merci beaucoup déraison! – Thomas
Échec dans MySQL 5.1.62 avec 'ERROR 1062 (23000): Dupliquer l'entrée '2' pour la clé 'PRIMARY''. – dotancohen
Votre solution ne fonctionne pas dans MySQL 5.5.22-log: '1706 - La mise à jour de clé primaire/clé de partition n'est pas permise car la table est mise à jour en tant que 'lae_marketing_invoice_history' et 't2'.' –
Je préfère l'approche suivante (Justin Cave a écrit quelque part similaire):
update MY_TABLE t1
set t1.MY_KEY = (case when t1.MY_KEY = 100 then 101 else 100 end)
where t1.MYKEY in (100, 101)
Mettre les valeurs clés comme premières littéraux dans la requête résout le problème de clés en double lors de la transaction. –
similaires à @ solution de Bart, mais j'utilisé une manière légèrement différente:
update t
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual)
where t.id in (100, 101);
Ceci est tout à fait la même , mais je connais mieux decode
puis case
.
Aussi, pour faire @ travail de solution de Bart pour moi, je dû ajouter un when
:
update t
set t.id = (case when t.id = 100 then 101 else 101 end)
where t.id in (100, 101);
J'ai aussi aucune idée de ce que, en détail, vous essayez d'accomplir. – bmargulies
Pourquoi voudriez-vous faire cela? Tu n'aimes pas tes clés primaires? ;) –
Et oui, c'est possible. Par exemple, dans perl, il y a le fetchall_hashref qui accepte tout nom de colonne à utiliser. – Konerak