【问题标题】:sql swap primary key valuessql交换主键值
【发布时间】:2010-05-11 12:25:25
【问题描述】:

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

【问题讨论】:

  • 我也不知道你想要完成什么。
  • 您为什么要这样做?你不喜欢你的主键吗? ;)
  • 是的,这是可能的。例如,在 perl 中有一个 fetchall_hashref 接受任何要使用的列名。

标签: sql primary-key swap


【解决方案1】:

为了简单起见,假设您有两条记录

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中的标准运行)。

【讨论】:

  • 您的解决方案在 MySQL 5.5.22-log 中不起作用:1706 - Primary key/partition key update is not allowed since the table is updated both as 'lae_marketing_invoice_history' and 't2'.
  • 在 MySQL 5.1.62 中失败,ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
  • Oracle 似乎也不允许在一个update 语句中使用两个表。 techonthenet.com/sql/update.php: "更新多张表时 SQL UPDATE 语句的语法是:"
  • 你会为 php 5.5 及更高版本做什么?
  • 错误代码:1706。不允许主键/分区键更新,因为表同时更新为“core_website”和“core_website2”。
【解决方案2】:

我更喜欢以下方法(贾斯汀凯夫在某处写过类似的):

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)

【讨论】:

  • 将原始键值作为文字放在查询中,解决了事务中键重复的问题。
  • 由于您在查询中只有一个表,因此不必为它起别名并将其放在每个列名之前。此外,此语法不适用于 SQL Server。
【解决方案3】:

与@Bart 的解决方案类似,但我使用的方式略有不同:

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

这完全一样,但我知道decodecase 更好。

另外,为了让@Bart 的解决方案对我有用,我必须添加一个when

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2016-08-08
    • 2012-10-28
    相关资源
    最近更新 更多