MySQL - транслитерация, перевод русского в транслит

:

Запись опубликована Блог компании Internet Business Promotion. Интернет и бизнес, веб-технологии и наши достижения в этих отраслях.Вы можете оставить комментарии здесь или тут

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

 

Первый вариант. Более гибкий, стандарт транслита легко конфигурируется редактированием таблички. Но более медленный, т.к. при кждом вызове функции будет обращение в таблице со схемой транслита.

1. Создаем табличку:

CREATE TABLE `fs_translit` (
`l_from` varchar(1) NOT NULL,
`l_to` varchar(2) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

 

2. Вносим в нее данные

INSERT INTO `fs_translit` (`l_from`, `l_to`) VALUES
('ъ','_'),
('А','A'),
('Ц','C'),
('Ы','Y'),
('й','j'),
('ё','jo'),
('ж','zh'),
('х','h'),
('ч','ch'),
('ш','sh'),
('щ','sh'),
('э','e-'),
('ю','yu'),
('я','ya'),
('а','a'),
('б','b'),
('в','v'),
('г','g'),
('д','d'),
('е','e'),
('з','z'),
('и','i'),
('к','k'),
('л','l'),
('м','m'),
('н','n'),
('о','o'),
('п','p'),
('р','r'),
('с','s'),
('т','t'),
('у','u'),
('ф','f'),
('ц','c'),
('ы','y'),
('А','A'),
('Б','B'),
('В','V'),
('Г','G'),
('Д','D'),
('Е','E'),
('З','Z'),
('И','I'),
('К','K'),
('Л','L'),
('М','M'),
('Н','N'),
('О','O'),
('П','P'),
('Р','R'),
('С','S'),
('Т','T'),
('У','U'),
('.',''),
(',',''),
('_','-'),
(' ','-'),
('\"',''),
('/',''),
('\\',''),
('[',''),
(']',''),
('{',''),
('}',''),
('ь',''''),
('Й','J'),
('Ё','JO'),
('Ж','ZH'),
('Х','H'),
('Ч','CH'),
('Ш','SH'),
('Щ','SH'),
('Э','E-'),
('Ю','YU'),
('Я','YA'),
('Ъ',''''),
('Ь','_');

COMMIT;

 

3. Собственно текст процедуры

CREATE DEFINER = 'ftpsearch'@'192.168.222.%' FUNCTION `_fs_transliterate`( str TEXT)
RETURNS text CHARSET cp1251
DETERMINISTIC
SQL SECURITY INVOKER
COMMENT ''

BEGIN
DECLARE done INT DEFAULT 0;
DECLARE src varCHAR(1);
DECLARE dst varCHAR(2);
DECLARE cur CURSOR FOR SELECT `l_from`, `l_to`  FROM fs_translit; /*  курсор для выборки из таблицы со схемо транслита */
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
/* открываем курсор */
open cur;
repeat
fetch cur into src, dst; /* идем по курсору */
set str = replace(str, src, dst); /* получаем исходный (русский сивол, строку на которуб он заменяется провизодим замену */
until done
 end repeat;
close cur; 
RETURN lower(str);
END;

 

Второй вариант. Сам код ф-ии более громоздкий и конфигурирование стандарта очень уксложнено но зато при вывзове ф-я не выдает запросов и работает быстрее:

DELIMITER $$

DROP FUNCTION IF EXISTS `_fs_transliterate_2` $$
CREATE DEFINER=`ftpsearch`@`192.168.222.%` FUNCTION `_fs_transliterate_2`( str TEXT) RETURNS text CHARSET cp1251
DETERMINISTIC
SQL SECURITY INVOKER

BEGIN
declare str2 varchar(2);
declare str3 text;
declare len int(11);
declare i int(11);
set str3 = '';
set i = 1;
set len = length(str);
 /*идем циклом по символам строки*/
while i <= len do  /*выполняем преобразование припомощи ф-ии ELT */
set str2 = elt(
instr(
' ,./АаАБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуфХхцЦЧчШшЩщЪъыЫЬьЭэЮюЯя[\]_{}',
substr(str,i,1)
),
'-',
'',
'',
'',
'A',
'a',
'A',
'B',
'b',
'V',
'v',
'G',
'g',
'D',
'd',
'E',
'e',
'JO',
'jo',
'ZH',
'zh',
'Z',
'z',
'I',
'i',
'J',
'j',
'K',
'k',
'L',
'l',
'M',
'm',
'N',
'n',
'O',
'o',
'P',
'p',
'R',
'r',
'S',
's',
'T',
't',
'U',
'u',
'f',
'H',
'h',
'c',
'C',
'CH',
'ch',
'SH',
'sh',
'SH',
'sh',
'\'',
'-',
'y',
'Y',
'-',
'\'',
'E-',
'e-',
'YU',
'yu',
'YA',
'ya',
'',
'',
'',
'-',
'',
''
);
if str2 is null then /* если преобразование не прошло успешно добавляем в рез-т исходный символ */
  set str2 = substr(str,i,1);
end if;
set str3 = concat(str3,str2);
set i = i + 1;
end while;

 return lower(str3);

END $$

DELIMITER ;

 

Собственно все. Какой вариант подойдет Вам - решайте исходя из Ваших целей.