CREATE FUNCTION->Illegal mix of collations

cat_crash

Новичок
CREATE FUNCTION->Illegal mix of collations

Интересную проблему нарыл работая с функуиями в MySQL. Возникла необходимость сделать процедуру перевода русских имен в транслит на стороне MySQL сервера.
Итак текст функции:
PHP:
CREATE FUNCTION translit(str VARCHAR(100))
  RETURNS varchar(100) CHARSET cp1251
BEGIN
  SET @x = str;
  SET @x = REPLACE(@x, CONVERT(_utf8 'А' USING CP1251), 'A');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Б' USING CP1251), 'B');
  SET @x = REPLACE(@x, CONVERT(_utf8 'В' USING CP1251), 'V');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Г' USING CP1251), 'G');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Д' USING CP1251), 'D');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Е' USING CP1251), 'E');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ё' USING CP1251), 'YO');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ж' USING CP1251), 'ZH');
  SET @x = REPLACE(@x, CONVERT(_utf8 'З' USING CP1251), 'Z');
  SET @x = REPLACE(@x, CONVERT(_utf8 'И' USING CP1251), 'I');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Й' USING CP1251), 'Y');
  SET @x = REPLACE(@x, CONVERT(_utf8 'К' USING CP1251), 'K');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Л' USING CP1251), 'L');
  SET @x = REPLACE(@x, CONVERT(_utf8 'М' USING CP1251), 'M');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Н' USING CP1251), 'N');
  SET @x = REPLACE(@x, CONVERT(_utf8 'О' USING CP1251), 'O');
  SET @x = REPLACE(@x, CONVERT(_utf8 'П' USING CP1251), 'P');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Р' USING CP1251), 'R');
  SET @x = REPLACE(@x, CONVERT(_utf8 'С' USING CP1251), 'S');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Т' USING CP1251), 'T');
  SET @x = REPLACE(@x, CONVERT(_utf8 'У' USING CP1251), 'U');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ф' USING CP1251), 'F');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Х' USING CP1251), 'H');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ц' USING CP1251), 'C');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ч' USING CP1251), 'CH');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ш' USING CP1251), 'SH');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Щ' USING CP1251), 'SCH');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ъ' USING CP1251), '');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ы' USING CP1251), 'I');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ь' USING CP1251), '');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Э' USING CP1251), 'E');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Ю' USING CP1251), 'YU');
  SET @x = REPLACE(@x, CONVERT(_utf8 'Я' USING CP1251), 'YA');
  SET @x = REPLACE(@x, CONVERT(_utf8 'а' USING CP1251), 'a');
  SET @x = REPLACE(@x, CONVERT(_utf8 'б' USING CP1251), 'b');
  SET @x = REPLACE(@x, CONVERT(_utf8 'в' USING CP1251), 'v');
  SET @x = REPLACE(@x, CONVERT(_utf8 'г' USING CP1251), 'g');
  SET @x = REPLACE(@x, CONVERT(_utf8 'д' USING CP1251), 'd');
  SET @x = REPLACE(@x, CONVERT(_utf8 'е' USING CP1251), 'e');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ё' USING CP1251), 'yo');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ж' USING CP1251), 'zh');
  SET @x = REPLACE(@x, CONVERT(_utf8 'з' USING CP1251), 'z');
  SET @x = REPLACE(@x, CONVERT(_utf8 'и' USING CP1251), 'i');
  SET @x = REPLACE(@x, CONVERT(_utf8 'й' USING CP1251), 'y');
  SET @x = REPLACE(@x, CONVERT(_utf8 'к' USING CP1251), 'k');
  SET @x = REPLACE(@x, CONVERT(_utf8 'л' USING CP1251), 'l');
  SET @x = REPLACE(@x, CONVERT(_utf8 'м' USING CP1251), 'm');
  SET @x = REPLACE(@x, CONVERT(_utf8 'н' USING CP1251), 'n');
  SET @x = REPLACE(@x, CONVERT(_utf8 'о' USING CP1251), 'o');
  SET @x = REPLACE(@x, CONVERT(_utf8 'п' USING CP1251), 'p');
  SET @x = REPLACE(@x, CONVERT(_utf8 'р' USING CP1251), 'r');
  SET @x = REPLACE(@x, CONVERT(_utf8 'с' USING CP1251), 's');
  SET @x = REPLACE(@x, CONVERT(_utf8 'т' USING CP1251), 't');
  SET @x = REPLACE(@x, CONVERT(_utf8 'у' USING CP1251), 'u');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ф' USING CP1251), 'f');
  SET @x = REPLACE(@x, CONVERT(_utf8 'х' USING CP1251), 'h');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ц' USING CP1251), 'c');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ч' USING CP1251), 'ch');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ш' USING CP1251), 'sh');
  SET @x = REPLACE(@x, CONVERT(_utf8 'щ' USING CP1251), 'sch');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ъ' USING CP1251), '');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ы' USING CP1251), 'i');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ь' USING CP1251), '');
  SET @x = REPLACE(@x, CONVERT(_utf8 'э' USING CP1251), 'e');
  SET @x = REPLACE(@x, CONVERT(_utf8 'ю' USING CP1251), 'yu');
  SET @x = REPLACE(@x, CONVERT(_utf8 'я' USING CP1251), 'ya');
  RETURN (@x);
END
На openSuse (MySQL 5.0.4x) проходит на ура, и работает. Но это домашний сервак :(
На centOS 5 (MySQL 5.0.5x) не работает :(((( выдает ошибку

...
mysql> SET @x = REPLACE(@x, CONVERT(_utf8 'А' USING CP1251), 'A');
ERROR 1270 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT), (cp1251_general_ci,IMPLICIT), (utf8_general_ci,COERCIBLE) for operation 'replace'
....

Уже перелопатил все возможные варианты - скопирывал my.cnf - не помогает. Кто сталкивался с подобными граблями - поделитесь панацеей.
 

Mols

Новичок
Было что-то подобное. Входящий параметр видимо приходит в latin1_swedish МуСКЛ очень "подробно" с кодировками свол работает))) Я как-то понаписал процедурок помню. Потом изменил кодировку для базы. А мускл в каждой процедуре "позапоминал" исходную кодировку для входящих параметров. В дампе было что-то вида
PHP:
CREATE FUNCTION translit(str VARCHAR(100) CHARSET cp1251)...
И когда я из приложения давал данные в ЮТФ8 - были проблемы))) Пока процедурки не переделал.
 

cat_crash

Новичок
x-yuri на обеих utf8
Mols дампы на обеих серверах абсолютно идентичны. Уже голову сломал...
 

x-yuri

Новичок
хорошо, а можешь показать список переменных, содержащих character_set в названии? Если отличаются, то чем? и character_set бд

-~{}~ 26.01.09 10:40:

а проблема твоя, скорее всего, в том, что ты не указал кодировку входного параметра и что кодировка бд у тебя latin1_swedish_ci на одной из бд, а такая она может быть из-за character_set_server (http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html). По этой же причине mysql "запомнил" кодировку входных параметров у Mols
 

cat_crash

Новичок
Suse:
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
| version | 5.0.45 |
| version_comment | SUSE MySQL RPM |


CentOS5:

| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
| version | 5.0.58 |
| version_comment | Source distribution |

Кстате таки после ALTER DATABASE database CHARACTER SET utf8 COLLATE utf8_general_ci;
функция сохранилась, но на выходе дает каркозяблики. Думаю с этим уже разбирусь.
x-yuri, Mols - cпасибо что наталкнули на мысль про кодировку всей базы а не отдельных таблиц!
 
Сверху