Есть ли там хранимая функция mysql, чтобы создать пул из URL-адреса (или любое значение действительно).
Таким образом, мой запрос может быть:
SELECT *, SLUG(url) FROM clients
Есть ли там хранимая функция mysql, чтобы создать пул из URL-адреса (или любое значение действительно).
Таким образом, мой запрос может быть:
SELECT *, SLUG(url) FROM clients
Это обновленная версия функции выше. Он намного быстрее, так как он избегает циклирования всех разрешенных символов и просто проверяет путем сравнения кодов ASCII.
DROP FUNCTION IF EXISTS `slugify`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost`
FUNCTION `slugify`(dirty_string varchar(200))
RETURNS varchar(200) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE x, y , z Int;
Declare temp_string, new_string VarChar(200);
Declare is_allowed Bool;
Declare c, check_char VarChar(1);
set temp_string = LOWER(dirty_string);
Set temp_string = replace(temp_string, '&', ' and ');
Select temp_string Regexp('[^a-z0-9\-]+') into x;
If x = 1 then
set z = 1;
While z <= Char_length(temp_string) Do
Set c = Substring(temp_string, z, 1);
Set is_allowed = False;
If !((ascii(c) = 45) or (ascii(c) >= 48 and ascii(c) <= 57) or (ascii(c) >= 97 and ascii(c) <= 122)) Then
Set temp_string = Replace(temp_string, c, '-');
End If;
set z = z + 1;
End While;
End If;
Select temp_string Regexp("^-|-$|'") into x;
If x = 1 Then
Set temp_string = Replace(temp_string, "'", '');
Set z = Char_length(temp_string);
Set y = Char_length(temp_string);
Dash_check: While z > 1 Do
If Strcmp(SubString(temp_string, -1, 1), '-') = 0 Then
Set temp_string = Substring(temp_string,1, y-1);
Set y = y - 1;
Else
Leave Dash_check;
End If;
Set z = z - 1;
End While;
End If;
Repeat
Select temp_string Regexp("--") into x;
If x = 1 Then
Set temp_string = Replace(temp_string, "--", "-");
End If;
Until x <> 1 End Repeat;
If LOCATE('-', temp_string) = 1 Then
Set temp_string = SUBSTRING(temp_string, 2);
End If;
Return temp_string;
END;;
DELIMITER ;
Я взял Slugifier из http://nastyhabit.wordpress.com/2008/09/25/mysql-slug-maker-function-aka-the-slugifier/
И изменил его, чтобы вначале не включать "-", (у нас был "$" в качестве первого символа)
Здесь мой результат:
DROP FUNCTION IF EXISTS `slugify`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost`
FUNCTION `slugify`(dirty_string varchar(200))
RETURNS varchar(200) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE x, y , z Int;
Declare temp_string, allowed_chars, new_string VarChar(200);
Declare is_allowed Bool;
Declare c, check_char VarChar(1);
set allowed_chars = "abcdefghijklmnopqrstuvwxyz0123456789-";
set temp_string = dirty_string;
Select temp_string Regexp('&') Into x;
If x = 1 Then
Set temp_string = replace(temp_string, '&', ' and ');
End If;
Select temp_string Regexp('[^a-z0-9]+') into x;
If x = 1 then
set z = 1;
While z <= Char_length(temp_string) Do
Set c = Substring(temp_string, z, 1);
Set is_allowed = False;
Set y = 1;
Inner_Check: While y <= Char_length(allowed_chars) Do
If (strCmp(ascii(Substring(allowed_chars,y,1)), Ascii(c)) = 0) Then
Set is_allowed = True;
Leave Inner_Check;
End If;
Set y = y + 1;
End While;
If is_allowed = False Then
Set temp_string = Replace(temp_string, c, '-');
End If;
set z = z + 1;
End While;
End If;
Select temp_string Regexp("^-|-$|'") into x;
If x = 1 Then
Set temp_string = Replace(temp_string, "'", '');
Set z = Char_length(temp_string);
Set y = Char_length(temp_string);
Dash_check: While z > 1 Do
If Strcmp(SubString(temp_string, -1, 1), '-') = 0 Then
Set temp_string = Substring(temp_string,1, y-1);
Set y = y - 1;
Else
Leave Dash_check;
End If;
Set z = z - 1;
End While;
End If;
Repeat
Select temp_string Regexp("--") into x;
If x = 1 Then
Set temp_string = Replace(temp_string, "--", "-");
End If;
Until x <> 1 End Repeat;
If LOCATE('-', temp_string) = 1 Then
Set temp_string = SUBSTRING(temp_string, 2);
End If;
Return temp_string;
END;;
DELIMITER ;
Хорошо работает, Но! Это довольно медленно. Если вы пытаетесь выбрать что-то из этого, вы добавите около 1000% времени в запрос по сравнению с выбором индекса, который был проиндексирован.
Забито за 500 результатов было 0,27 секунды Непробито (через mysql) было .00003 секунды
Для ввода данных эта функция будет работать отлично! Просто вставьте пробитые данные в предварительно определенный столбец (THATS INDEXED, так почему бы вам не выбрать что-то, что было пробито?)
Примечание. Текст, который должен быть "slugified", должен быть сначала в нижнем регистре, так как эта функция не обрабатывает буквы верхнего регистра (преобразует их в "-" ).
Я не уверен, рекомендую ли я это делать в SQL, но вот парень, который сделал для вас функцию "slugify":
http://nastyhabit.wordpress.com/2008/09/25/mysql-slug-maker-function-aka-the-slugifier/
Я добавил несколько строк в функцию Robert, чтобы убедиться, что slug всегда уникален.
Это происходит прямо до конца функции, как вы можете видеть ниже. Убедитесь, что вы указываете имя таблицы без скобок [].
SELECT COUNT(*) INTO i FROM [table name goes here] WHERE slug LIKE CONCAT('%',temp_string,'%');
If i > 0 Then
Set temp_string = CONCAT(temp_string,'-',i+1);
End If;
Return temp_string;
END;;
DELIMITER ;
Я реализовал свою собственную функцию slug, поддерживающую акцентированные символы, любой вклад в нее приветствуем.
https://github.com/falcacibar/mysql-routines-collection/blob/master/generate_slug.func.sql
Не стесняйтесь публиковать любые предложения, ошибки или любую проблему или вклад в github или здесь, но лучше github