Bir ara değişim değişkenine sahip olmanın şu şekilde en iyi uygulama olduğuna inanıyorum:
update z set c1 = @c := c1, c1 = c2, c2 = @c
Birincisi, her zaman çalışır; ikincisi, veri türünden bağımsız olarak çalışır.
İkisine rağmen
update z set c1 = c1 ^ c2, c2 = c1 ^ c2, c1 = c1 ^ c2
ve
update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2
genellikle çalışıyoruz, bu arada sadece sayı veri türü için ve taşmayı önlemek sizin sorumluluğunuzdadır, XOR'u imzalı ve işaretsiz arasında kullanamazsınız, ayrıca taşma olasılığı için toplam kullanamazsınız.
Ve
update z set c1 = c2, c2 = @c where @c := c1
c1 0 veya NULL ise veya sıfır uzunluklu dize veya yalnızca boşluk ise çalışmıyor.
Değiştirmemiz gerek
update z set c1 = c2, c2 = @c where if((@c := c1), true, true)
İşte komut dosyaları:
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)
UPDATE table SET X = Y, Y = Xbunu SQL'de yapmanın standart yoludur, yalnızca MySQL yanlış davranır.