#1062 — Дубликат записи ‘1’ для ключа 1 — Дубликатов записей не найдено

#mysql #sql #phpmyadmin

#mysql #sql #phpmyadmin

Вопрос:

Поэтому при попытке добавить автоинкремент в поле появляется #1062 — Дубликат записи ‘1’ для ключа 1 . Я попытался удалить первичный ключ и повторно добавить его, и это работает нормально (чего, я полагаю, не было бы, если бы были дубликаты?)

Но когда я пытаюсь добавить автоинкремент в поле, он выдает ошибку. Это дает мне возможность просмотра, которая запускает следующий SQL:

 SELECT *
FROM `myTbl`
WHERE CONCAT_WS( "-", 11 ) = "1"
ORDER BY 11
LIMIT 0 , 30
  

Однако это возвращает пустой результирующий набор.. предполагая, что дубликатов нет. Итак, если дубликатов нет, почему я не могу добавить автоинкремент?

Комментарии:

1. Каким вы ожидаете результата CONCAT_WS( "-", 11 ) ? Я всегда получаю там 11…

2. Пожалуйста, опубликуйте результат SHOW CREATE TABLE myTbl и команду, которую вы используете для добавления автоинкремента. Также обратите внимание, что CONCAT_WS('-', 11) = '1' всегда будет оцениваться FALSE . Вы не можете использовать порядковый номер поля в WHERE предложении так, как вы это делаете ORDER BY .

3. Чтобы вы не думали, что я сумасшедший, я не писал этот SQL — он был сгенерирован phpMyAdmin при нажатии кнопки просмотра после того, как он сгенерировал ошибку. Я думаю, что приведенный ниже плакат (Майкл Миор) правильный, и сейчас я пытаюсь это решение.

Ответ №1:

У вас есть какие-либо строки со значением 0 или NULL для этого столбца? ALTER TABLE может привести к повторной последовательности первичных ключей. В случае ключа, равного 0, MySQL попытается присвоить ему значение 1, что приведет к сбою, если ключ 1 уже существует.

Попробуйте изменить любые 0 NULL значения или в столбце на что-то более высокое (и неиспользуемое).

Комментарии:

1. @Micheal, что произойдет, если вы попытаетесь вставить 0 в PK, зависит от SQL-режима, в котором находится MySQL. Если он находится в режиме расслабленного режима старой школы, он не заменит 1, а даст следующее автоматическое увеличение. Если он находится в рекомендованном строгом режиме, он будет вставлен 0 .

2. @Johan Хорошая мысль. Тем не менее, я все еще подозреваю, что это решит проблему.

3. @MichaelMior Нечто подобное произошло со мной в таблице, содержащей всего два столбца, оба в качестве первичных ключей без каких-либо значений (возможно, одна запись NULL NULL). Я попытался ВСТАВИТЬ значения (’25’, ’35’) и получил ту же ошибку. После ручного добавления случайных значений SQL-запросы ВСТАВЛЯЮТ, ОБНОВЛЯЮТ работу по мере необходимости. Есть идеи, почему нулевые значения или отсутствие значений могут вызвать эту повторяющуюся ошибку?

4. @fat_mike Я бы посоветовал вам опубликовать это как отдельный вопрос.

Ответ №2:

Ответ Майкла Миора работает, если вы можете изменить данные в таблице. Однако существует также обходной путь, который позволяет сохранить данные нетронутыми (я тестировал это на MySQL 5.5). Помните, что использование нулевого значения в качестве первичного ключа в MySQL не рекомендуется только по этой причине. Если вы можете избавиться от нуля, сделайте это.

Отключить автоматическую генерацию значения при вставке нуля:

 SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
  

Добавьте АВТО_ИНКРЕМЕНТ в свой столбец:

 ALTER TABLE ... AUTO_INCREMENT;
  

Повторно включите автоматическую генерацию значений:

 SET SQL_MODE='';
  

Должно быть очевидно, что вставка данных в таблицу во время всей этой операции не может быть разрешена. В противном случае в столбце будут нежелательные нулевые значения.

Ответ №3:

 SELECT *                           <<-- Select * is an anti-pattern
FROM myTbl 
WHERE CONCAT_WS( "-", 11 ) = "1"   <<-- You are not selecting a column
ORDER BY 11                        <<-- This however does refer to a column.
LIMIT 30 OFFSET 0
  

перепишите запрос на

 SELECT field1, field2, field3, ...., field11
FROM myTbl 
WHERE COALESCE(field1, field2, field3, field11) = '1'
ORDER BY field11               
LIMIT 30 OFFSET 0
  

Если вы хотите вставить строку, используйте код, подобный этому:

 INSERT INTO table1 (/*do not list the PK!*/ field2, field3, field4) 
  VALUES ('a', 'test' ,'b' ,'example'); 
  

Если вы хотите выбрать все повторяющиеся строки, используйте:

 SELECT id, count(*) as duplicate_count
FROM table1
GROUP BY id
HAVING duplicate_count > 1
  

Вам нужно будет обновить те идентификаторы, которые указаны как дубликаты.

Другой вариант — добавить дополнительный столбец и удалить старый PK.

 ALTER TABLE table1 ADD COLUMN new_id unsigned integer not null auto_increment primary key;
ALTER TABLE table1 DROP COLUMN id;
ALTER TABLE table1 CHANGE COLUMN newid id;
  

Комментарии:

1. Если я не ошибаюсь, проблема в том, что OP не может добавить AUTO_INCREMENT в столбец. Я не понимаю, как это решает проблему.