在MySQL中的两个不同的行上交换两列主键冲突

时间:2014-04-17 05:56:07

标签: mysql sql join swap

我正在尝试在两个不同的行(角色)上交换两列。我知道我可以通过设置用户变量来做到这一点,但如果可能的话,我试图在一个查询中完成所有操作。

我的查询是:

UPDATE table AS t1, table AS t2 
SET t1.role = 'standby', t2.role = 'primary'
WHERE t1.sysid = t2.sysid AND t1.role = 'primary' AND t2.role = 'standby';

表结构是

sysid | role    | devid
1     | primary | dev1
1     | standby | dev2

主键是sysid,role

问题似乎是交易时主键之间的冲突,错误:Error Code: 1706. Primary key/partition key update is not allowed since the table is updated both as 't1' and 't2'.

由于MySQL从左到右处理,我尝试先将临时值设置为t1以避免冲突,但它仍然失败并出现同样的错误:

SET t1.role = 'tmp', t2.role = 'primary', t1.role = 'standby'

有没有办法用MySQL实现这个目标?

3 个答案:

答案 0 :(得分:2)

您可以使用临时值来交换角色。选择一个尚不存在但不会导致密钥违规的值。使用事务来保证数据完整性。

START TRANSACTION;
UPDATE table SET role = 'temprole' WHERE sysid = 1 and role = 'primary';
UPDATE table SET role = 'primary' WHERE sysid = 1 and role = 'standby';
UPDATE table SET role = 'standby' WHERE sysid = 1 and role = 'temprole';
COMMIT;

答案 1 :(得分:0)

UPDATE table AS t1 join table AS t2 on t1.sysid=t2.sysid
SET t1.role = if(t1.role = 'primary' AND t2.role = 'standby', 
                 'standby', 
                 if (t2.role = 'primary' AND t1.role = 'standby','primary',t1.role));

加入两个表并根据条件更新一个

更新

我交换了列,但实际上PK并不允许执行更新。在调用之前应该设置约束检查

答案 2 :(得分:0)

自从我不得不手动创建一个SQL语句以来,已经有几年了,但是翻转翻转是可能的吗?

UPDATE table SET role=IF(role='primary', 'secondary', 'primary') 
WHERE sysid = 1
ORDER BY role ASC;