我发现一个非常奇怪的行为,比较mysql中的字符。mysql - 为什么认为右括号等于ö(o变音符)?
最简单的函数来再现是这样的:
set names utf8 collate utf8_general_ci;
drop function if exists contains_bracket;
delimiter ;;
CREATE DEFINER=`db`@`%` FUNCTION `contains_bracket`(str varchar(255) CHARSET utf8) RETURNS varchar(255) CHARSET utf8
begin
declare i, result int;
declare letter varchar(1);
set result = 0;
set i = 1;
set str = lower(str);
while i <= length(str) do
set letter = substring(str, i, 1);
if letter = ']' then
set result = 1;
end if;
set i = i + 1;
end while;
return result;
end;;
delimiter ;
函数应该返回1,如果该参数包含一个右括号]
,否则为0。奇怪的是,在这个功能中,变音符ö
被认为等于]
。
测试这样的:
select contains_bracket('[a]'), contains_bracket('abc'), contains_bracket('äöü'), contains_bracket('ö')
会给
-------------------------------
| '[a]' | 'abc' | 'äöü' | 'ö' |
-------------------------------
| 1 | 0 | 1 | 1 |
-------------------------------
这到底是怎么回事?有人可以解释吗?当使用utf8_general_ci
时,']' = 'ö'
是否为真,是否是mysql中的一个错误,或者是否有某些我错过的东西?
编辑:
连接字符集和整理是非常重要的,因为存储函数和过程保持字符集和校对他们创造了其一生中是活跃的。
请记住,在phpmyadmin中,数据交换是默认在utf8中。连接collatiom不会改变这一点。例如,当连接校对是latin1的,而我们在字符串中查询发送非ASCII字符,其价值将被损坏(例如,当我们输入'ä'
(UTF8),服务器将看到_latin1'ä'
)
您能否在第一次开始之前添加DETERMINISTIC并告诉我您是否仍然收到不正确的值? –
你可能有一个原因,但为什么你在地球上循环,如果你可以使用mysql本地函数,即instr? –
@krishKM我正在循环出于其他原因。这只是一个表现现象的功能。 –