我正在尝试在两个不同的行(角色)上交换两列。我知道我可以通过设置用户变量来做到这一点,但如果可能的话,我试图在一个查询中完成所有操作。
我的查询是:
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实现这个目标?
答案 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;