2010-05-11 8 views
13

¿es posible intercambiar valores de clave primaria entre dos conjuntos de datos? Si es así, ¿cómo lo haría uno?valores clave clave de intercambio sql

+0

También tengo ni idea de lo que, en detalle, que está tratando de lograr. – bmargulies

+1

¿Por qué querrías hacer eso? ¿No te gustan tus llaves principales? ;) –

+0

Y sí, es posible. Por ejemplo, en perl existe el fetchall_hashref que acepta cualquier nombre de columna para ser utilizado. – Konerak

Respuesta

10

Déjenos en aras de la simplicidad se supone que tiene dos registros

id name 
--------- 
1 john 

id name 
--------- 
2 jim 

ambos de la tabla t (pero pueden provenir de diferentes tablas)

que podría hacer

UPDATE t, t as t2 
SET t.id = t2.id, t2.id = t.id 
WHERE t.id = 1 AND t2.id = 2 

Nota : La actualización de claves principales tiene otros efectos secundarios y tal vez el enfoque preferido sería dejar las claves primarias tal como están e intercambiar los valores de todos los th e otras columnas.

Advertencia: La razón por la cual el t.id = t2.id, t2.id = t.id funciona es porque en SQL la actualización ocurre en un nivel de transacción. El t.id no es variable y = no es una asignación. Podría interpretarlo como "establecer t.id al valor t2.id tenido antes del efecto de la consulta, establecer t2.id al valor t.id tenido antes del efecto de la consulta". Sin embargo, es posible que algunas bases de datos no realicen el aislamiento adecuado; consulte esto question por ejemplo (sin embargo, ejecutar la consulta anterior, que probablemente se considere actualización de varias tablas, se comportó de acuerdo con el estándar en mysql).

+0

muchas gracias sinrazón! – Thomas

+0

falla en MySQL 5.1.62 con 'ERROR 1062 (23000): entrada duplicada '2' para la clave 'PRIMARY''. – dotancohen

+2

Su solución no funciona en MySQL 5.5.22-log: '1706 - La clave primaria/clave de partición no está actualizada ya que la tabla se actualiza como 'lae_marketing_invoice_history' y 't2'. –

5

Yo prefiero el siguiente enfoque (Justin Cueva escribió similares en alguna parte):

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

Al poner los valores de clave sin procesar como literales en la consulta se resuelve el problema de claves duplicadas durante la transacción. –

1

similares a @ solución de Bart, pero utiliza una forma ligeramente diferente:

update t 
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual) 
where t.id in (100, 101); 

Esto es exactamente lo mismo , pero sé decode mejor que case.

Además, para hacer el trabajo @ solución de Bart para mí he tenido que añadir un when:

update t 
set t.id = (case when t.id = 100 then 101 else 101 end) 
where t.id in (100, 101);