我發現一個非常奇怪的行爲,比較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我正在循環出於其他原因。這只是一個表現現象的功能。 –