ฉันเชื่อว่าการมีตัวแปรแลกเปลี่ยนกลางเป็นแนวทางปฏิบัติที่ดีที่สุดในลักษณะดังกล่าว:
update z set c1 = @c := c1, c1 = c2, c2 = @c
ประการแรกมันใช้งานได้เสมอ ประการที่สองมันทำงานโดยไม่คำนึงถึงประเภทข้อมูล
แม้จะมีทั้งสองอย่าง
update z set c1 = c1 ^ c2, c2 = c1 ^ c2, c1 = c1 ^ c2
และ
update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2
โดยปกติจะใช้งานได้เฉพาะสำหรับประเภทข้อมูลตัวเลขเท่านั้นและเป็นความรับผิดชอบของคุณในการป้องกันการล้นคุณไม่สามารถใช้ XOR ระหว่างเซ็นชื่อและไม่ได้ลงนามคุณยังไม่สามารถใช้ผลรวมสำหรับความเป็นไปได้ที่มากเกินไป
และ
update z set c1 = c2, c2 = @c where @c := c1
ไม่ทำงานถ้า c1 เป็น 0 หรือ NULL หรือสตริงความยาวเป็นศูนย์หรือเว้นวรรค
เราต้องเปลี่ยนเป็น
update z set c1 = c2, c2 = @c where if((@c := c1), true, true)
นี่คือสคริปต์:
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 = X
เป็นวิธีมาตรฐานในการดำเนินการใน SQL มีเพียง MySQL ที่ทำงานผิดปกติ