2013-11-15 2 views
1

У меня есть таблица MySQL со следующей схемойзначения Обновляется, из столбца с ограничением PRIMARY KEY

+-------+-------------+------+-----+---------+----------------+ 
| 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

'id' должен быть первичным ключом и' title' уникальным. У вас это в другом месте в определении таблицы. –

+0

Стандартное решение - нажать «b» на «c», а затем «a» на «b», а затем «c» на «a». Это вариант? – Strawberry

+0

@Strawberry Не совсем. Мне нужно сделать это в одном запросе. –

ответ

1
START TRANSACTION ; 
    UPDATE prime SET title = '[email protected]#$%' 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 является основным ключом, но в других случаях у вас будут нежелательные последствия.

+0

Да, я согласен с вашим комментарием. Я мог бы добавить «ELSE title». –

+0

Это тоже сработает. Вероятно, он был бы менее эффективным, поскольку он проверял бы все остальные строки (новый заголовок будет равен существующему). Вероятно, он также заблокировал бы всю таблицу. –

+0

Я не думаю, что это проверит все остальные строки. 'ELSE' здесь, вероятно, работает как' default' 'switch'. –

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. это не работает.

Я использую его с идентификатором, например, что:

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 следует обновить раздельно.

Смежные вопросы