Без учета регистра ЗАМЕНА в MySQL? - PullRequest
26 голосов
/ 14 апреля 2011

MySQL выполняет почти все сравнения строк в соответствии с параметрами сортировки по умолчанию ... кроме команды REPLACE. У меня сортировка без учета регистра и мне нужно выполнить регистр без учета регистра REPLACE. Есть ли способ заставить REPLACE использовать текущую сортировку, а не проводить сравнения с учетом регистра? Я готов обновить MySQL (в настоящее время работает 5.1), чтобы получить дополнительную функциональность ...

mysql> charset utf8 collation utf8_unicode_ci;
Charset changed

mysql> select 'abc' like '%B%';
+------------------+
| 'abc' like '%B%' |
+------------------+
|                1 |
+------------------+

mysql> select replace('aAbBcC', 'a', 'f');
+-----------------------------+
| replace('aAbBcC', 'a', 'f') |
+-----------------------------+
| fAbBcC                      |   <--- *NOT* 'ffbBcC'
+-----------------------------+

Ответы [ 7 ]

19 голосов
/ 14 апреля 2011

Если replace(lower()) не работает, вам нужно создать другую функцию.

7 голосов
/ 27 апреля 2016

Мои 2 цента.

Поскольку многие люди обновили MySQL до MariaDB, им будет доступна новая функция REGEXP_REPLACE. Используйте его как обычную замену, но шаблон является регулярным выражением.

Это рабочий пример:

UPDATE `myTable`
SET `myField` = REGEXP_REPLACE(`myField`, '(?i)my insensitive string', 'new string') 
WHERE `myField` REGEXP '(?i)my insensitive string'

Опция (?i) делает все последующие совпадения нечувствительными к регистру (если поместить в начало шаблона, как у меня, то все нечувствительно).

Смотрите здесь для получения дополнительной информации: https://mariadb.com/kb/en/mariadb/pcre/

Редактировать: начиная с MySQL 8.0, теперь вы также можете использовать функцию regexp_replace, см. Документацию: https://dev.mysql.com/doc/refman/8.0/en/regexp.html

4 голосов
/ 03 декабря 2012

Альтернативная функция для одного человека, которого говорит fvox.

DELIMITER |
CREATE FUNCTION case_insensitive_replace ( REPLACE_WHERE text, REPLACE_THIS text, REPLACE_WITH text )
RETURNS text
DETERMINISTIC 
BEGIN
    DECLARE last_occurency int DEFAULT '1';

    IF LCASE(REPLACE_THIS) = LCASE(REPLACE_WITH) OR LENGTH(REPLACE_THIS) < 1 THEN
         RETURN REPLACE_WHERE;
    END IF;

    WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0  DO
      BEGIN
        SET last_occurency = Locate(LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE));
         SET REPLACE_WHERE = Insert( REPLACE_WHERE, last_occurency, LENGTH(REPLACE_THIS), REPLACE_WITH);
         SET last_occurency = last_occurency + LENGTH(REPLACE_WITH);
      END;
    END WHILE;
    RETURN REPLACE_WHERE;
END;
|
DELIMITER ;

Маленький тест:

SET @str = BINARY 'New York';
SELECT case_insensitive_replace(@str, 'y', 'K');

Ответы: New Kork

0 голосов
/ 16 октября 2015

В случае «специальных» символов происходит непредвиденное поведение:

SELECT case_insensitive_replace('A', 'Ã', 'a')

Дает

a

Что является неожиданным ... поскольку мы хотим заменить только Ã, а не A

Что еще более странно:

SELECT LOCATE('Ã', 'A');

дает

0

Что является правильным результатом ... похоже, связано с кодированием параметровхранимая процедура ...

0 голосов
/ 25 января 2015

В предыдущих ответах и ​​ссылке на pento.net аргументы LOCATE() в нижнем регистре.

Это пустая трата ресурсов, так как LOCATE по умолчанию не учитывает регистр:

mysql> select locate('el', 'HELLo');
+-----------------------+
| locate('el', 'HELLo') |
+-----------------------+
|                     2 |
+-----------------------+

Вы можете заменить

WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0 DO

с

WHILE Locate(REPLACE_THIS, REPLACE_WHERE, last_occurency ) > 0 DO

и т.д.

0 голосов
/ 22 июня 2013

Эта модификация ответа Луиста позволяет заменить иглу иглой с другой оболочкой (смена двух линий).

DELIMITER |
CREATE FUNCTION case_insensitive_replace ( REPLACE_WHERE text, REPLACE_THIS text, REPLACE_WITH text )
RETURNS text
DETERMINISTIC 
BEGIN
  DECLARE last_occurency int DEFAULT '1';

  IF LENGTH(REPLACE_THIS) < 1 THEN
    RETURN REPLACE_WHERE;
  END IF;

  WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0  DO
    BEGIN
      SET last_occurency = Locate(LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency);
      SET REPLACE_WHERE = Insert( REPLACE_WHERE, last_occurency, LENGTH(REPLACE_THIS), REPLACE_WITH);
       SET last_occurency = last_occurency + LENGTH(REPLACE_WITH);
    END;
  END WHILE;
  RETURN REPLACE_WHERE;
END;
|
DELIMITER ;
0 голосов
/ 15 мая 2013

Я пошел с http://pento.net/2009/02/15/case-insensitive-replace-for-mysql/ (в ответе fvox), который выполняет поиск без учета регистра с заменой с учетом регистра и без изменения регистра того, какие символы должны быть неизменными в других местах искомой строки.

N.B. комментарий внизу на той же странице, в котором говорится, что CHAR (255) должен быть изменен на VARCHAR (255) - это, похоже, потребовалось и для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...