在不違反唯一約束的情況下交換MySQL中的行值
在MySQL中,經常需要交換錶中兩行的值同時保持對特定列的唯一約束。但是,如果違反唯一約束,使用帶有 CASE 子句的典型 UPDATE 語句可能會導致重複條目錯誤。
問題
問題的出現是因為 MySQL逐行處理更新,在每次更改後檢查唯一約束違規情況。在提供的範例中:
UPDATE tasks SET priority = CASE WHEN priority=2 THEN 3 WHEN priority=3 THEN 2 END WHERE priority IN (2,3);
MySQL 將優先權為 2 的第一行更新為優先權 3。但是,當它嘗試將優先權為 3 的第二行更新為優先權 2 時,會遇到違規,因為 3 已經存在作為唯一值存在。
解
不幸的是,在不使用虛假值或多個查詢的情況下,不可能在 MySQL 中完成行值交換。這是由於 MySQL 獨特的約束處理行為所致。
要解決此限制,可以利用封裝在事務中的以下兩語句方法:
START TRANSACTION ; UPDATE tasks SET priority = CASE WHEN priority = 2 THEN -3 WHEN priority = 3 THEN -2 END WHERE priority IN (2,3) ; UPDATE tasks SET priority = - priority WHERE priority IN (-2,-3) ; COMMIT ;
這種方法有效地交換值透過分配負值作為臨時佔位符。在事務內,MySQL 將更新視為單一操作,從而防止違反唯一約束。
以上是如何在尊重唯一約束的同時交換 MySQL 中的行值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!