2010-05-11 77 views
13

是否可以在两个数据集之间交换主键值?如果是这样,那么如何做到这一点?sql swap主键值

+0

我也有不知道是什么,详细,你所要完成。 – bmargulies 2010-05-11 12:28:01

+1

你为什么要这么做?你不喜欢你的主键吗? ;) – 2010-05-11 12:28:20

+0

是的,这是可能的。例如,在perl中,有一个fetchall_hashref接受要使用的任何列名称。 – Konerak 2010-05-11 12:29:09

回答

10

让我们为简单起见,假设你有两个记录

id name 
--------- 
1 john 

id name 
--------- 
2 jim 

无论从表t(但他们可能来自不同的表)

你可以做

UPDATE t, t as t2 
SET t.id = t2.id, t2.id = t.id 
WHERE t.id = 1 AND t2.id = 2 

注: 更新主键有其他副作用,也许首选的方法是将主键保持原样并交换全部值其他栏目。

注意事项: t.id = t2.id, t2.id = t.id工作原因是因为在SQL中更新发生在事务级别。 t.id不可变,=未分配。您可以将其解释为“将t.id设置为t2.id在查询效果之前具有的值,将t2.id设置为值t.id在查询效果之前具有的值”。但是,有些数据库可能没有做适当的隔离,例如见question(但是,运行在查询之上,可能被认为是多表更新,按照mysql中的标准进行操作)。

+0

非常感谢谢谢! – Thomas 2010-05-11 13:17:37

+0

在MySQL 5.1.62中失败,出现错误1062(23000):重复键入'PRIMARY'的条目'2'。 – dotancohen 2012-08-08 15:31:36

+2

您的解决方案在MySQL 5.5.22-log中不起作用:'1706 - 由于表更新为'lae_marketing_invoice_history'和't2',因此不允许使用主键/分区键更新。“ – 2012-08-08 15:19:50

5

我更喜欢下面的方法(贾斯汀窟写下类似的地方):

update MY_TABLE t1 
set t1.MY_KEY = (case when t1.MY_KEY = 100 then 101 else 100 end) 
where t1.MYKEY in (100, 101) 
+0

将原始键值作为文字在查询中解决交易过程中重复键的问题。 – 2017-05-05 22:43:14

1

类似@ Bart的解决方案,但我用了一个稍微不同的方式:

update t 
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual) 
where t.id in (100, 101); 

这是不太一样,但我知道decode更好,然后case

此外,为了使@巴特的解决方案为我工作,我不得不添加when

update t 
set t.id = (case when t.id = 100 then 101 else 101 end) 
where t.id in (100, 101);