更新具有PRIMARY KEY约束的列的值

时间:2013-11-15 16:52:45

标签: mysql

我有一个包含以下架构的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;

2 个答案:

答案 0 :(得分: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;

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

答案 1 :(得分:0)

使用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应该分开更新。