2010-05-11 16 views
13

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

+0

J'ai aussi aucune idée de ce que, en détail, vous essayez d'accomplir. – bmargulies

+1

Pourquoi voudriez-vous faire cela? Tu n'aimes pas tes clés primaires? ;) –

+0

Et oui, c'est possible. Par exemple, dans perl, il y a le fetchall_hashref qui accepte tout nom de colonne à utiliser. – Konerak

Répondre

10

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).

+0

merci beaucoup déraison! – Thomas

+0

Échec dans MySQL 5.1.62 avec 'ERROR 1062 (23000): Dupliquer l'entrée '2' pour la clé 'PRIMARY''. – dotancohen

+2

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'.' –

5

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

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. –

1

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);