Ich habe glauben, dass ein Zwischen Austausch Variable die beste Praxis in einer solchen Art und Weise ist:
update z set c1 = @c := c1, c1 = c2, c2 = @c
Erstens, es funktioniert immer; Zweitens funktioniert es unabhängig vom Datentyp.
Trotz beider
update z set c1 = c1^c2, c2 = c1^c2, c1 = c1^c2
und
update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2
arbeiten in der Regel nur für Zahlendatentyp von der Art und Weise, und es liegt in Ihrer Verantwortung Überlauf zu verhindern, können Sie nicht XOR verwenden, um zwischen signiert und unsigniert, Sie können die Summe auch nicht für überlaufende Möglichkeiten verwenden.
Und
update z set c1 = c2, c2 = @c where @c := c1
funktioniert nicht wenn c1 0 oder NULL oder leeren String oder nur Leerzeichen.
Wir brauchen es
update z set c1 = c2, c2 = @c where if((@c := c1), true, true)
Hier ist die Skripte zu
ändern:
mysql> create table z (c1 int, c2 int)
-> ;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into z values(0, 1), (-1, 1), (pow(2, 31) - 1, pow(2, 31) - 2)
-> ;
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.02 sec)
mysql> update z set c1 = c1^c2, c2 = c1^c2, c1 = c1^c2;
ERROR 1264 (22003): Out of range value for column 'c1' at row 2
mysql> update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2;
ERROR 1264 (22003): Out of range value for column 'c1' at row 3
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.02 sec)
mysql> update z set c1 = c2, c2 = @c where @c := c1;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.00 sec)
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 1 | 0 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.00 sec)
mysql> update z set c1 = @c := c1, c1 = c2, c2 = @c;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.00 sec)
mysql>update z set c1 = c2, c2 = @c where if((@c := c1), true, true);
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 1 | 0 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.00 sec)
als eine Notiz, 'UPDATE-Tabelle SET X = Y, Y = X 'ist die Standardmethode, es in SQL zu tun, nur MySQL verhält sich falsch. –