Tôi tin rằng có một biến đổi trung gian là thực hành tốt nhất theo cách như vậy:
update z set c1 = @c := c1, c1 = c2, c2 = @c
Đầu tiên, nó hoạt động luôn; thứ hai, nó hoạt động bất kể kiểu dữ liệu.
Mặc dù of Both
update z set c1 = c1^c2, c2 = c1^c2, c1 = c1^c2
và
update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2
đang làm việc thường, chỉ dành cho kiểu dữ liệu số bằng cách này, và nó là trách nhiệm của bạn để ngăn chặn tràn, bạn không thể sử dụng XOR giữa đã ký và chưa ký, bạn cũng không thể sử dụng tổng cho khả năng tràn.
Và
update z set c1 = c2, c2 = @c where @c := c1
không được làm việc nếu c1 là 0 hoặc NULL hoặc không có chiều dài chuỗi hoặc chỉ không gian.
Chúng ta cần thay đổi nó để
update z set c1 = c2, c2 = @c where if((@c := c1), true, true)
Đây là kịch bản:
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)
làm ghi chú, 'CẬP NHẬT bảng SET X = Y, Y = X' là cách tiêu chuẩn để thực hiện nó trong SQL, chỉ các lỗi của MySQL. –