sql交换主键值

sql交换主键值,sql,primary-key,swap,Sql,Primary Key,Swap,是否可以在两个数据集之间交换主键值?如果是这样的话,你会怎么做呢?为了简单起见,我们假设你有两条记录 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 注: 更新主键还有其他副作用,可能首选的方法是保持主键不变,并交换所有其

是否可以在两个数据集之间交换主键值?如果是这样的话,你会怎么做呢?

为了简单起见,我们假设你有两条记录

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值”。但是,有些数据库可能没有进行适当的隔离,例如(但是,运行上面的查询,这可能被认为是多表更新,按照mysql中的标准执行)。

我更喜欢以下方法(Justin Cave在某处写过类似的文章):


与@Bart的解决方案类似,但我使用了一种稍微不同的方法:

update t
set t.id=(select decode(t.id, 100, 101, 101, 100) from dual)
where t.id in (100, 101);
这是完全相同的,但我知道
decode
case
更好

此外,为了使@Bart的解决方案对我有效,我必须在时添加一个

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

我也不知道你到底想完成什么。你为什么要这么做?你不喜欢你的主键吗?;)是的,这是可能的。例如,在perl中有fetchall\u hashref,它接受要使用的任何列名。您的解决方案在MySQL 5.5.22-log中不起作用:
1706-主键/分区键更新是不允许的,因为表同时更新为“lae\u marketing\u invoice\u history”和“t2”。
在MySQL 5.1.62中失败,出现
错误1062(23000):键“PRIMARY”的重复条目“2”
。Oracle似乎也不允许一个语句中包含两个表。
update
语句:更新多个表(Oracle中不允许)时,SQL UPDATE语句的语法是:“对于PHP5.5及以上版本,您会怎么做?错误代码:1706。”。不允许主键/分区键更新,因为该表同时更新为“core_website”和“core_website2”。将原始键值作为文本放在查询中可以解决事务期间出现重复键的问题。由于查询中只有一个表,因此无需对其进行别名并将其放在每个列名之前。此外,此语法不适用于SQL Server。
update t
set t.id = (case when t.id = 100 then 101 else 101 end)
where t.id in (100, 101);