在不违反唯一约束的情况下交换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中文网其他相关文章!