【问题标题】:Updating value, of a Column with PRIMARY KEY constraint更新具有 PRIMARY KEY 约束的列的值
【发布时间】:2013-11-15 16:52:44
【问题描述】:

我有一个具有以下架构的 MySQL 表

+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(7)      | NO   | UNI | NULL    | auto_increment |
| title | varchar(20) | NO   | PRI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

这是里面的内容。

+----+-------+
| id | title |
+----+-------+
|  1 | a     |
|  2 | b     |
+----+-------+

问题:我想在单个查询中交换值,以便表格现在变成

+----+-------+
| id | title |
+----+-------+
|  1 | b     |
|  2 | a     |
+----+-------+

我试过了:UPDATE myTable SET title = CASE id WHEN 1 THEN "b" WHEN 2 THEN "a" END;

但它给了我一个错误ERROR 1062 (23000): Duplicate entry 'b' for key 'PRIMARY'

我该怎么办?

在其中一个链接中找到的解决方案似乎是目前唯一的方法,但我仍在寻找更好的解决方案

START TRANSACTION;
UPDATE prime SET title = CASE id WHEN 1 THEN "$b" WHEN 2 THEN "$a" END;
UPDATE prime SET title = CASE id WHEN 1 THEN SUBSTRING(title,2)  WHEN 2 THEN SUBSTRING(title,2) END;
COMMIT;

【问题讨论】:

  • id 应该是主键并且title 是唯一的。您在表定义中使用相反的方式。
  • 标准的解决方案是将'b'推送到'c',然后将'a'推送到'b',再将'c'推送到'a'。这是一个选择吗?
  • @Strawberry 不完全是。我需要在单个查询中执行此操作。
  • how to swap values of two rows in mysql without violating unique constraint? 的可能重复项(但交换 VARCHAR 值比交换 INT 值要复杂一些。)

标签: mysql


【解决方案1】:
START TRANSACTION ;
    UPDATE prime SET title = 'zzzzz$$$$$xxxxx!@#$%' WHERE id = 1 ;

    UPDATE prime SET title = 'a' WHERE id = 2 ;

    UPDATE prime SET title = 'b' WHERE id = 1 ;
COMMIT ;

评论,与独特问题无关:

在您的更新语句中使用WHERE,除非您想更新表的所有行。您的声明:

UPDATE myTable SET title = CASE id WHEN 1 THEN 'b' WHEN 2 THEN 'a' END;

(如果有效)它还将尝试使用NULL 值更新所有其他行(使用id >= 3),因为CASE 具有隐含的ELSE NULL 部分。当然它会失败,因为 title 是主键,但在其他情况下,您会产生不良影响。

【讨论】:

  • 是的,我同意你的评论。我可以在那里添加ELSE title
  • 这也行,是的。虽然它可能会降低效率,因为它会检查所有其他行(新标题等于现有标题。)它也可能会锁定整个表。
  • 我认为它不会检查所有其他行。 ELSE 这里可能像 defaultswitch 一样工作。
  • 如果您没有WHERE 子句,则表示您要更新表的所有行。
【解决方案2】:

通过 PIMARY 键帮助使用 ORDER BY title

UPDATE myTable SET title = CASE id WHEN 1 THEN "a" WHEN 2 THEN "b" ElSE title END WHERE id in (1,2) ORDER BY id DESC;

如果不起作用,请将方向更改为 ASC 或 ORDER BY 标题。不要忘记 ELSE。没有它是行不通的。

我把它和id一起用,像这样:

UPDATE `table1` SET `id` = CASE `id` WHEN 1 THEN 2 WHEN 2 THEN 3 WHEN 0 THEN 1 ELSE `id` END WHERE `id` IN ( 1, 2, 0 ) ORDER BY `id` DESC 

一切正常, 但是如果更新 0=>3,3=>2,2=>1 - 0 应该单独更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多