è possibile scambiare i valori delle chiavi primarie tra due set di dati? Se sì, come si farebbe?sql scambia i valori delle chiavi primarie
risposta
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).
grazie mille irragionevole! – Thomas
Errore in MySQL 5.1.62 con 'ERROR 1062 (23000): voce duplicata '2' per la chiave 'PRIMARY''. – dotancohen
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'. –
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)
L'inserimento dei valori della chiave non elaborata come valori letterali nella query risolve il problema problema delle chiavi duplicate durante la transazione. –
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);
Inoltre ho idea di che cosa, in particolare, si sta cercando di realizzare. – bmargulies
Perché vorresti farlo? Non ti piacciono le tue chiavi primarie? ;) –
E sì, è possibile. Ad esempio, in perl c'è il fetchall_hashref che accetta qualsiasi nome di colonna da utilizzare. – Konerak