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



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



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

646   11  

11 ответов:

select * from foo where upper(bar) = upper(?);

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

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

использование другого движка базы данных не может быть и речи - будет гораздо больше случаев, когда он ведет себя иначе, чем просто как (кроме того, вы проверили параметры сортировки, используемые базами данных? Они идентичны в каждом случае? Если нет, вы можете забыть порядок на колонках varchar, работающих одинаково)

Используйте Arel:

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

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

в Postgres, вы можете сделать это:

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

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

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');

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

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

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

    SELECT id FROM person WHERE name REGEXP 'john';

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

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

вы также можете рассмотреть возможность проверить searchlogic плагин, который делает НРАВИТСЯ / МНЕ НРАВИТСЯ переключатель для вас.

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

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

оба попали бы на "какой-то неровный текст здесь" Только первый ударит по "некоторому неровному тексту здесь"

преобразование в верхний лучше всего, поскольку он охватывает совместимый синтаксис для 3 наиболее часто используемых бэкендов базы данных Rails. PostgreSQL, MySQL и SQLite поддерживают этот синтаксис. Он имеет (незначительный) недостаток, что вам нужно прописать строку поиска в вашем приложении или в строке условий, что делает ее немного уродливее, но я думаю, что совместимость, которую вы получаете, делает ее достойной.

MySQL и sqlite3 для того, иметь нечувствительные к регистру оператора like. Только PostgreSQL имеет чувствительный к регистру, как оператор и оператор PostgreSQL-specific (в руководстве) ILIKE для поиска без учета регистра. Вы можете указать ILIKE insead of LIKE в своих условиях в приложении Rails, но имейте в виду, что приложение перестанет работать под MySQL или SQLite.

третий вариант может заключаться в том, чтобы проверить, какой компонент database engine вы используете, и соответствующим образом изменить строку поиска. Это может быть лучше сделать путем взлома / monkeypatching адаптеров подключения ActiveRecord и иметь Адаптер PostgreSQL изменяет строку запроса, чтобы заменить " LIKE "на" ILIKE " перед выполнением запроса. Однако это решение является наиболее запутанным и в свете более простых способов, таких как верхний регистр обоих терминов, я думаю, что это не worh усилия (хотя вы получите много очков брауни для этого).

Comments

    Ничего не найдено.