Поведение MySQL UPDATE - PullRequest
       7

Поведение MySQL UPDATE

1 голос
/ 20 мая 2009

mysql> обновить имя таблицы set fieldname = 'C200900674' где fieldname - 'C200900673';

ОШИБКА 1062 (23000): дубликат записи 'C200900674-2008-0-1' для ключа 1

Есть мысли или предложения по этому поводу? У нас кто-то случайно сделал это обновление со знаком минус вместо знака равенства. Видимо он пытался изменить все записи меньше, чем это значение? Хотя он буквенно-цифровой и действительно неполный. Кроме того, некоторое количество записей было обновлено до того, как возникла эта ошибка, и никакой обратной связи не было. Ничего подобного «Запрос в порядке, X строк затронут (0,00 с)», поэтому мы не знали, сколько их изменилось. autocommit = 1, поэтому нет возможности отката.

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

Ответы [ 2 ]

2 голосов
/ 30 июня 2009

Всякий раз, когда возникает сомнение в том, как Mysql интерпретировал предложение WHERE, измените его на SELECT.

SELECT fieldname - 'C200900673' FROM tablename;

И

SELECT fieldname FROM tablename WHERE fieldname - 'C200900673';

Посмотрите, какое значение возвращает первый выбор и какие строки находит второй.

К сожалению, поскольку Mysql довольно слабо разбирается в числовых / строковых преобразованиях, особенно в сериях 4.x, и даже в нестрогих 5.x, черт возьми ... даже в строгом моде трудно сказать, что именно неправильно без всех деталей вашей конфигурации Mysql. Это может быть связано с тем, что имя поля было приведено к какому-либо числу, как и C200900673, в основном работающий:

update tablename set fieldname = 'C200900674' where NUMBER - NUMBER;

Что можно перевести на:

update tablename set fieldname = 'C200900674' where 1;

В любом случае, надеюсь, у вас есть резервная копия!

0 голосов
/ 20 мая 2009

Если ваша таблица использует механизм хранения InnoDB, никакого вреда не было. Даже при autocommit = 1 запрос выполняется только «все или ничего». Тот факт, что вы получили сообщение об ошибке, является доказательством того, что БД не касалась ваших данных. Всякий раз, когда вы получаете ОШИБКУ, сообщение «затронутые строки х» опускается.

Даже в случае, если ограничение уникальности не было бы нарушено, запрос потерпел бы неудачу с другой ошибкой:

ОШИБКА 1292 (22007): усечено неверное значение DOUBLE: 'fieldname'

Это потому, что знак минус заставил бы MySQL попытаться вычислить значение содержимого поля минус что-то еще. Это не работает. Вы только не увидели эту ошибку, потому что другой «попал туда первым».

...