SQLite:如何交换仅留下 ID 列的两行

问题描述 投票:0回答:3

我有两个整数,它们是表中现有两行的一些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 sqlite swap
3个回答
6
投票

您应该能够使用标准 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;

3
投票

如果没有唯一约束或允许负值(情况可能并非如此),戈登的答案就有效。 如果存在仅强制执行正的唯一值的约束,那么这两种解决方案都不起作用,特别是如果可以同时进行许多此类更新的话。 在这种情况下,我建议您使用临时表来存储正在交换的行的事务(为了一致性):

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;

0
投票

我没有评论所需的 50 声望,所以我需要发布作为答案。这是关于 Hiko Haieto 的回答。请注意,如果您的外键引用 ID 没有“ON DELETE CASCADE”约束,则他的解决方案不起作用。 你将达到步骤

DELETE FROM my_table WHERE id = 5;

然后您将面临外键约束失败错误。

使用 Gordon 的两步方法对我来说很有效,因为 SQLite 确实支持负主键 id。

© www.soinside.com 2019 - 2024. All rights reserved.