like и lower

Lithium366

Новичок
like и lower

Необходимо осуществить регистронезависимый поиск в нескольких таблицах по полям name и content.
Желательно полностью средствами MySQL


Пробую делать вот так:
PHP:
sprintf("SELECT * FROM staticpages, news, callbacks WHERE lower(name) like %%lower('%s')%% OR lower(content) 
like %%lower('%s')%%", $_REQUEST['search'], $_REQUEST['search'])
Результат:
Warning: SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%lower('fgh')% OR lower(content) like %lower('fgh')%' at line 1

Какие существуют решения данной проблемы?
 

HraKK

Мудак
Команда форума
Уверены что хотите все время конвертировать весь контент во время поиска? Или у вас чай с кофе выдается совместно с нажатием кнопки - найти?
 

Фанат

oncle terrible
Команда форума
Lithium366
открою тебе СТРРАШНУЮ тайну.
база данных и так ищет без учета регистра.
так что все втои извращения просто не нужны
 

Lithium366

Новичок
Автор оригинала: HraKK
Уверены что хотите все время конвертировать весь контент во время поиска? Или у вас чай с кофе выдается совместно с нажатием кнопки - найти?
там проще. cake возвращает ассоциативный массив в котором news, staticpages и callbacks уже в нормальном виде.

По поводу своего запроса - исправлюсь, надо бы везде указать перед названиями столбцов в where названия таблиц. Тем не менее основная проблема остается та же
 

Фанат

oncle terrible
Команда форума
товарищ тормозит.
надо подождать, пока дойдет
 

Lithium366

Новичок
Автор оригинала: *****
Lithium366
открою тебе СТРРАШНУЮ тайну.
база данных и так ищет без учета регистра.
так что все втои извращения просто не нужны
Хм... Надо проверить в MySQL. Во всяком случае делал по примеру PG, там, насколько я помню, были отличия. Спасибо
 

oracloid

совсем кукус
Автор оригинала: *****
Lithium366
открою тебе СТРРАШНУЮ тайну.
база данных и так ищет без учета регистра.
так что все втои извращения просто не нужны
открою еще одну тайну.
сказанное верно только при использовании case-insensitive collation.
в любой СУБД, где есть такое понятие.

There is a convention for collation names: They start with the name of the character set with which they are associated, they usually include a language name, and they end with _ci (case insensitive), _cs (case sensitive), or _bin (binary).

то есть, если имя используемого collation заканчивается на _cs, то поиск будет проводиться с учетом регистра.
 

oracloid

совсем кукус
обычная строка - это набор символов + collation

binary strings - это последовательность байтов, не связанных ни с какими кодировками.
в таких строках можно хранить любой тип информации.
если поместить туда обычную строку, она тоже будет рассматриваться как байты.

_bin collation использует сравнение байт-в-байт.
 

camka

не самка
Автор оригинала: oracloid
_bin collation использует сравнение байт-в-байт.
Неверно. Это значит только регистрозависимое сравнение, _учитывая_ позицию следования символа в национальном алфавите.
 

oracloid

совсем кукус
Автор оригинала: camka
регистрозависимое сравнение, _учитывая_ позицию следования символа в национальном алфавите.
так это и есть побайтное сравнение.
сравниваются последовательно числовые значения байтов в строке.

читаем мануал:

This means that they have no character set, and sorting and comparison are based on the numeric values of the bytes in the values.
 

camka

не самка
oracloid
Вы привели цитату из описания типов binary и varbinary, а не из описания бинарных колейшнов.

И, я тогда не пойму, зачем столько разных _bin колейшнов, если все они сравнивают побайтно одинаково? Почему не используется один бинарный колейшн для всех случаев?
 

oracloid

совсем кукус
Автор оригинала: camka
Вы привели цитату из описания типов binary и varbinary, а не из описания бинарных колейшнов.
ок, смотрим раздел "10.5 Collation Issues":
http://dev.mysql.com/doc/refman/5.0/en/charset-binary-op.html

The BINARY operator casts the string following it to a binary string. This is an easy way to force a comparison to be done byte by byte rather than character by character.

Автор оригинала: camka
И, я тогда не пойму, зачем столько разных _bin колейшнов, если все они сравнивают побайтно одинаково? Почему не используется один бинарный колейшн для всех случаев?
читаем чуть ниже:

Every character set has a binary collation. For example, the binary collation for the latin1 character set is latin1_bin, so if the table default character set is latin1, these two column definitions are equivalent:

CHAR(10) BINARY
CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin

думаю, несколько разных _bin колейшнов нужны для использования с оператором COLLATE.
если у вас таблица объявлена как latin1, то нужно юзать latin1_bin, если cp1251 - cp1251_bin.
почему сделано именно так я не знаю,
но, в любом случае, это будет приведение к бинарным данным, и побайтное сравнение.
 

camka

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

oracloid

совсем кукус
ну тогда все ясно.
разобрались совместными усилиями :)
 
Сверху