我有两个整数,它们是表中现有两行的一些ID。
我想要做的是只交换两行的值,除了它们的 ID。
例如,如果我给出了 ID 5 和 13, 我想改变
ID columnA columnB columnC
5 343 "ABC" null
13 90 "DEF" "ZY"
进入
ID columnA columnB columnC
5 90 "DEF" "ZY"
13 343 "ABC" null
我该怎么做? ID列不是自动增量的,所以我不能鲁莽地插入具有任意ID的临时行。
您应该能够使用标准 SQL 来执行此操作:
update t
set id = (case when id = 5 then 13 else 5 end)
where id in (5, 13);
如果
id
列具有唯一约束,那么您可能会违反唯一约束。 如果发生这种情况,一种方法是两步法。 假设 id
始终为正:
update t
set id = (case when id = 5 then -13 else -5 end)
where id in (5, 13);
update t
set id = - id
where id < 0;
如果没有唯一约束或允许负值(情况可能并非如此),戈登的答案就有效。 如果存在仅强制执行正的唯一值的约束,那么这两种解决方案都不起作用,特别是如果可以同时进行许多此类更新的话。 在这种情况下,我建议您使用临时表来存储正在交换的行的事务(为了一致性):
BEGIN;
CREATE TEMPORARY TABLE my_temp AS SELECT * FROM my_table WHERE id = 5;
DELETE FROM my_table WHERE id = 5;
UPDATE my_table SET id = 5 WHERE id = 13;
UPDATE my_temp SET id = 13 WHERE id = 5;
INSERT INTO my_table SELECT * FROM my_temp;
DROP TABLE my_temp;
COMMIT;
我没有评论所需的 50 声望,所以我需要发布作为答案。这是关于 Hiko Haieto 的回答。请注意,如果您的外键引用 ID 没有“ON DELETE CASCADE”约束,则他的解决方案不起作用。 你将达到步骤
DELETE FROM my_table WHERE id = 5;
然后您将面临外键约束失败错误。
使用 Gordon 的两步方法对我来说很有效,因为 SQLite 确实支持负主键 id。