Как вы пишете без учета регистра для MySQL и Postgres? - PullRequest
64 голосов
/ 15 октября 2008

Я использую базу данных MySQL для разработки, но развертываю ее в Heroku, которая использует Postgres. Heroku обрабатывает практически все, но мои независимые от регистра слова Like становятся чувствительными к регистру. Я мог бы использовать операторы iLike, но моя локальная база данных MySQL не справляется с этим.

Каков наилучший способ написания запроса без учета регистра, который совместим как с MySQL, так и с Postgres? Или мне нужно написать отдельные операторы Like и iLike в зависимости от базы данных, с которой работает мое приложение?

Ответы [ 11 ]

73 голосов
/ 11 октября 2009

Мораль этой истории такова: не используйте другой программный стек для разработки и производства. Никогда.

Вы просто получите ошибки, которые не сможете воспроизвести в dev; Ваше тестирование будет бесполезным. Только не делай этого.

Использование другого движка базы данных не может быть и речи - будет FAR больше случаев, когда он ведет себя иначе, чем просто LIKE (кроме того, проверяли ли вы параметры сортировки, используемые базами данных? Они идентичны в КАЖДОМ случае? , вы можете забыть ORDER BY на столбцах varchar, работающих одинаково)

58 голосов
/ 15 октября 2008
select * from foo where upper(bar) = upper(?);

Если вы укажете параметр в верхнем регистре в вызывающей программе, вы можете избежать второго вызова функции.

36 голосов
/ 14 апреля 2012

Использование Arel:

Author.where(Author.arel_table[:name].matches("%foo%"))

matches будет использовать оператор ILIKE для Postgres и LIKE для всего остального.

13 голосов
/ 15 октября 2008

В postgres вы можете сделать это:

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

Я не уверен, есть ли аналог для MySQL, но вы всегда можете сделать это немного уродливо, но должно работать как в MySQL, так и в postgres:

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');
8 голосов
/ 20 июня 2012

Есть несколько ответов, ни один из которых не является очень удовлетворительным.

  • LOWER (бар) = LOWER (?) будет работать на MySQL и Postgres, но, вероятно, будет ужасно работать на MySQL : MySQL не будет используйте его индексы из-за функции LOWER. На Postgres вы можете добавить функциональный индекс (на LOWER (bar) ), но MySQL не поддерживает это.
  • MySQL будет (если вы не установили сопоставление с учетом регистра) автоматически сопоставлять без учета регистра и использовать его индексы. ( бар =? ).
  • Из вашего кода вне базы данных сохраните поля bar и bar_lower , где bar_lower содержит результат lower (bar) . (Это также возможно при использовании триггеров базы данных). (См. Обсуждение этого решения на Drupal ). Это неуклюже, но, по крайней мере, одинаково работает практически во всех базах данных.
5 голосов
/ 01 августа 2012

REGEXP нечувствителен к регистру (если не используется с BINARY) и может использоваться, например, так ...

    SELECT id FROM person WHERE name REGEXP 'john';

... чтобы соответствовать 'Джону', 'Джону', 'Джону' и т. Д.

2 голосов
/ 27 апреля 2012
2 голосов
/ 05 марта 2010

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

1 голос
/ 12 января 2011

Вы также можете использовать ~ * в postgres, если вы хотите сопоставить подстроку в блоке. ~ соответствует чувствительной к регистру подстроке, ~ * нечувствительной к регистру подстроке. Это медленная операция, но могу ли я найти ее полезной для поиска.

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

И то, и другое попало бы в "Неравномерный текст здесь" Только первый попадет на «НЕКОТОРЫЙ НЕВЕННЫЙ ТЕКСТ»

1 голос
/ 11 октября 2009

Вы можете также рассмотреть возможность использования плагина searchlogic , который делает для вас переключатель LIKE / ILIKE

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