2010-05-11 18 views
13

ist es möglich, Primärschlüssel Werte zwischen zwei Datensätze auszutauschen? Wenn ja, wie würde man das tun?sql Swap Primärschlüssel Werte

+0

Ich habe auch keine Ahnung, was im Detail, versuchen Sie zu erreichen. – bmargulies

+1

Warum möchten Sie das tun? Magst du deine Primärschlüssel nicht? ;) –

+0

Und ja, es ist möglich. Zum Beispiel gibt es in Perl die Funktion fetchall_hashref, die jeden zu verwendenden Spaltennamen akzeptiert. – Konerak

Antwort

10

Lassen Sie uns aus Gründen der Einfachheit nehme an, Sie haben zwei Datensätze

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

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

sowohl aus der Tabelle t (aber sie aus verschiedenen Tabellen kommen können)

Sie

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

Hinweis tun könnte : Das Aktualisieren von Primärschlüsseln hat andere Nebeneffekte und vielleicht wäre der bevorzugte Ansatz, die Primärschlüssel so zu belassen, wie sie sind, und die Werte von allen zu vertauschen Die anderen Spalten.

Vorbehalt: Der Grund, warum die t.id = t2.id, t2.id = t.id funktioniert, ist, weil in SQL die Aktualisierung auf einer Transaktionsebene geschieht. Die t.id ist nicht variabel und = ist keine Zuweisung. Du könntest es als "setze t.id auf den Wert t2.id hatte vor der Wirkung der Abfrage, setzen Sie t2.id auf den Wert t.id hatten vor der Wirkung der Abfrage". Einige Datenbanken führen jedoch unter Umständen keine ordnungsgemäße Isolation durch, siehe zum Beispiel question (allerdings läuft die obige Abfrage, die wahrscheinlich als Multi-Tabellen-Update betrachtet wird, verhält sich gemäß dem Standard in mysql).

+0

danke viel unvernünftig! – Thomas

+0

Fehler in MySQL 5.1.62 mit 'ERROR 1062 (23000): Doppelter Eintrag '2' für Schlüssel 'PRIMARY''. – dotancohen

+2

Ihre Lösung funktioniert nicht in MySQL 5.5.22-log: '1706 - Die Aktualisierung des Primärschlüssels/Partitionsschlüssels ist nicht erlaubt, da die Tabelle sowohl als 'lae_marketing_invoice_history' als auch 't2' aktualisiert wird. –

5

Ich ziehe den folgenden Ansatz (Justin Cave ähnlich irgendwo geschrieben):

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

Durch das Einfügen der Raw-Schlüsselwerte als Literale in die Abfrage wird das Problem behoben Problem der doppelten Schlüssel während der Transaktion. –

1

Ähnlich @ Barts Lösung, aber ich habe eine etwas andere Art und Weise:

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

Dies ist ganz das gleiche , aber ich weiß decode besser als case.

, auch @ Barts Lösung Arbeit für mich zu machen hatte ich ein when hinzuzufügen:

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