2010-05-11 16 views
13

è possibile scambiare i valori delle chiavi primarie tra due set di dati? Se sì, come si farebbe?sql scambia i valori delle chiavi primarie

+0

Inoltre ho idea di che cosa, in particolare, si sta cercando di realizzare. – bmargulies

+1

Perché vorresti farlo? Non ti piacciono le tue chiavi primarie? ;) –

+0

E sì, è possibile. Ad esempio, in perl c'è il fetchall_hashref che accetta qualsiasi nome di colonna da utilizzare. – Konerak

risposta

10

diamo per ragioni di semplicità si supponga di avere due record

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

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

sia da tavolo t (ma possono provenire da diverse tabelle)

si potrebbe fare

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

Nota : L'aggiornamento delle chiavi primarie ha altri effetti collaterali e forse l'approccio preferito sarebbe lasciare le chiavi primarie come sono e scambiare i valori di tutti e altre colonne.

Avvertenza: Il motivo per cui lo t.id = t2.id, t2.id = t.id funziona è perché in SQL l'aggiornamento avviene a livello di transazione. t.id non è variabile e = non è un'assegnazione. Potresti interpretarlo come "imposta t.id sul valore t2.id prima dell'effetto della query, imposta t2.id sul valore che t.id aveva prima dell'effetto della query". Tuttavia, alcuni database potrebbero non fare un corretto isolamento, si veda questo question per esempio (tuttavia, eseguendo la query sopra, che è probabilmente considerata aggiornamento multi tabella, si è comportata secondo lo standard in mysql).

+0

grazie mille irragionevole! – Thomas

+0

Errore in MySQL 5.1.62 con 'ERROR 1062 (23000): voce duplicata '2' per la chiave 'PRIMARY''. – dotancohen

+2

La tua soluzione non funziona in MySQL 5.5.22-log: '1706 - L'aggiornamento della chiave primaria/chiave di partizione non è consentito poiché la tabella viene aggiornata sia come 'lae_marketing_invoice_history' che come 't2'. –

5

preferisco il seguente approccio (Justin Cave ha scritto simile da qualche 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

L'inserimento dei valori della chiave non elaborata come valori letterali nella query risolve il problema problema delle chiavi duplicate durante la transazione. –

1

Simile a @ soluzione di Bart, ma ho usato un modo leggermente diverso:

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

Questa è proprio la stessa cosa , ma so decode meglio di case.

Inoltre, per rendere il lavoro @ soluzione di Bart per me ho dovuto aggiungere un when:

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