Как обновить уникальный столбец в Mysql до верхнего регистра?

#mysql #sql

#mysql #sql

Вопрос:

в mysql 5.7 :

Я хочу выполнить UPDATE foobar SET foo = 'Bar' WHERE foo = 'bar'

foo уникален

но я получаю #1062 - Duplicate entry 'Bar' for key 'foobar_foo_unique'

что мне делать?

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

1. Вы, кажется, хотите установить строчное значение в верхний регистр . Вы неправильно сформулировали заголовок своего вопроса?

2. Пожалуйста, покажите схему таблицы (включая роль и тип ключа foo или как там ее на самом деле зовут) и пример данных и реальный запрос (не перефразированный), который воспроизводит проблему.

3. из ошибки я понимаю, что у вас в таблице 2 значения. Тот, который содержит Bar и тот, который содержит bar . Поскольку foo уникален, вы не можете изменить bar значение на Bar , потому что Bar оно уже существует.

4. Я здесь с Габриэлем. select * from foobar where lower(foo) = 'bar' чтобы посмотреть, что у вас есть, а затем принять решение, как это сделать.

5. в моей таблице есть (id: int(11) primary auto_increment, name: varchar(255) unique) . у меня есть строка, подобная (id=1, name='one') . я запускаю UPDATE projects SET name='One' WHERE name='one' из кода. и я использую name для отображения в пользовательском интерфейсе.

Ответ №1:

Похоже, вам нужна сортировка с учетом регистра для столбца (или, возможно, для базы данных, но это другой вопрос).

Вы можете установить это при определении таблицы:

 CREATE TABLE foobar (
    foo VARCHAR(80) COLLATE utf8_bin
);
  

Вы можете определить столбец как уникальный в таблице или создать отдельный индекс / ограничение:

 CREATE TABLE foobar (
    foo VARCHAR(80) COLLATE utf8_bin UNIQUE
);
  

Обратите внимание, что это имеет приятный побочный эффект, заключающийся в том, что сравнения в столбце также чувствительны к регистру, поэтому where foo = 'bar' и where foo = 'Bar' различны.

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

1. спасибо за ваш ответ. можно ли использовать учет регистра для ОБНОВЛЕНИЯ, но без учета регистра для ВСТАВКИ? я хочу, чтобы столбец foo был уникальным, скорее это прописные или строчные буквы, но я хочу иметь возможность обновлять символ столбца до верхнего или нижнего регистра…

2. @AliDahaghin . . . Я думаю, что вам следует задать новый вопрос с большим количеством примеров того, что вы хотите делать и не хотите делать. Я думаю, что это отвечает на вопрос, который вы задали здесь об уникальности.

3. но это невероятно глупое ограничение для mysql без всякой причины. Mysql ДОЛЖЕН распознавать, когда вы обновляете уникальное значение для этого элемента, даже если вы установили для него то же уникальное значение (или изменен регистр).

Ответ №2:

Кажется, у вас есть функциональный уникальный индекс в foo столбце, такой как

 CREATE UNIQUE INDEX foobar_foo_unique
ON foobar( (ascii(foo)) );
  

Рассмотрим это :

 mysql> CREATE TABLE foobar( foo VARCHAR(80) );

mysql> CREATE UNIQUE INDEX foobar_foo_unique ON foobar( (ascii(foo)) );

mysql> INSERT INTO foobar VALUES('Bar');

mysql> INSERT INTO foobar VALUES('bar');

mysql> INSERT INTO foobar VALUES('Bar');  

Duplicate entry ....

mysql> SELECT * FROM foobar;

 ------ 
| foo  |
 ------ 
| Bar  |
| bar  |
 ------ 
  

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

Demo

Другой случай: у вас могут быть пробелы, обтекающие (даже между буквами). В этом случае вы можете подумать, что столкнулись с проблемой дублирования. Рассмотрим это Demo также.

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

1. привет, спасибо за твой ответ. второй запрос не может выполняться в версии 5.7. есть ли какая-либо альтернатива?

2. да, это невозможно для версии 8.0.13 - @AliDahaghin , но здесь есть проблема, если это уникальный индекс, вы не можете вставить Bar и bar одновременно. Возможно, строки имеют пробелы вокруг них. Взгляните на это

Ответ №3:

Вам нужно удалить уникальное ограничение:

 ALTER TABLE foobar DROP INDEX constraint_name;
  

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

1. я не могу. мне нужно быть уникальным… потому что я обновляю его с помощью пользовательских вводов