2016-05-30 3 views
0

Я пытаюсь обновить таблицу, которая содержит два столбца; id и position. id уникален и автоматически увеличивается. position уникален, но не автоматически увеличивается, и на самом деле его нужно установить вручную.Увеличение уникального столбца в каждой строке в одном запросе

Мне нужно изменить все строки с положением, большим или равным 5 (или любым другим числом, которое я предоставляю), чтобы увеличить их на единицу. Это мой код:

UPDATE slides 
SET position = position + 1 
WHERE position >= 5; 

К сожалению, она возвращает следующее сообщение об ошибке:

Error : Duplicate entry '2' for key 'slides_position_unique'

Как обновить все эти уникальные номера, не вызывая конфликтов, как я делаю это? Я пробовал подзапрос, который находит все обновляемые строки и возвращает их в обратном порядке, но это не помогает.


CREATE TABLE slides 
    (id int(10) unsigned NOT NULL AUTO_INCREMENT, 
    user_id int(10) unsigned NOT NULL, 
    position int(10) unsigned NOT NULL, 
    PRIMARY KEY (id), 
    UNIQUE KEY slides_position_unique (position), 
    KEY slides_user_id_foreign (user_id), 
    CONSTRAINT slides_user_id_foreign 
    FOREIGN KEY (user_id) REFERENCES users (id)) 
+0

какой вывод 'show create table' slides'? – Asenar

+1

Не помещайте дополнительную информацию в комментарии - вместо этого отредактируйте свой вопрос и добавьте новую информацию в вопрос. На этот раз я сделал это для вас. Помните об этом в будущем. Благодарю. –

ответ

3

Проблема заключается в ограничении уникальности - во время обновления значения не являются уникальными. Вы можете сделать это в сделке или уронить ограничение, а затем добавить его:

ALTER TABLE slides DROP index slides_position_unique; 
UPDATE slides SET position = position + 1 WHERE position >= 1; 
ALTER TABLE slides ADD CONSTRAINT slides_position_unique UNIQUE (position); 

См http://sqlfiddle.com#!9/66e0d8 для работы примера.

+0

Иисус. Это очень хороший момент, вполне возможно, что человек, который сказал мне сделать странное гнездование, был, по сути, неправильным. – Forest

+0

Это возвращает ту же ошибку. – Forest

+0

Глядя на инструкцию CREATE, я вижу, что у вас есть УНИКАЛЬНОЕ ограничение на позицию. Я думаю, что UPDATE создаст дубликаты в столбце позиции. Проверьте этот скрипт SQL: http: //sqlfiddle.com#! 9/fe46ee/1, и вы можете видеть, что обновление работает по назначению на простых входных данных. – martin

0

Ошибка довольно понятна: применение этого запроса дало повторяющиеся строки. Чтобы избежать этого, измените свой запрос. Я полагаю, это означает либо удаление WHERE position >= 1 (для обновления всех строк), либо добавление другого условия для исключения slides.position < 1.

Может быть, это более простой запрос работает для вас:

UPDATE slides 
SET position = position + 1 
WHERE position >= 1 AND position IS NOT NULL 

Вы можете, вероятно, использовать UPDATE IGNORE slides set position = position+1, но это может сделать вас потерять несколько строк.

+0

Это возвращает ту же ошибку. Я также попытался поэкспериментировать с удалением 'WHERE position> = 1', но безрезультатно. – Forest

+0

, так что некоторые из ваших данных недействительны. Является ли тип позиции = 'int' и' null' запрещенным? Я просто отредактировал свой ответ, чтобы исключить неверную позицию. В противном случае, если вы в состоянии потенциально потерять некоторые некогерентные данные, вы можете попробовать «update ignore» – Asenar

+0

Нуль запрещен, да. Это просто 'int'. Я очень смущен этой проблемой. – Forest

1

Вы можете использовать заказ по обновлению. Как mysql doc факты:

If the ORDER BY clause is specified, the rows are updated in the order that is specified

Это приведет:

UPDATE slides 
SET position = position + 1 
WHERE position >= 5 
ORDER BY position DESC; 

Таким образом, вы обновляете больше первого, то больше-1, то больше-2, и т.д ... и уникальных индекс всегда освобождается перед назначением следующей строки.

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