這個棘手的問題,我花了整整二天解決。
因為 MySql 是在 FreeBSD 6.2 上。用Console去Mysql中查詢會是正確的中文字。
但是由C# Select 出後,就會是亂碼!他的校對是這樣的:
資料庫 offline 校對 utf8_unicode_ci
L資料表 conn_status 型態 MyISAM 校對 utf8_general_ci
L 欄位 u_name varchar(20) 校對 latin1_bin <=== 注意
u_name 是有中文字的欄位,校對設定是 latin1_bin (這個關鍵花了一天才找到)。
為了解決亂碼的問題,寫了一個函數來轉成正確的中文字。
轉碼程式
假設由資料庫Select取出的字串是 instr,經由下面的程式轉出才會得到正確的 Unicode。
原因在於Unicode 是1-2個char所組成,一個字元是由1-2位元byte組成,回傳的就是正確的UNICODE中文字
private string ConvertUnicode(string instr)
{
char[] wdchars = instr.ToCharArray();
byte[] resbyte = new byte[wdchars.Length*2 ]; //預設長度是 char 的二倍
int ii = 0;
foreach (char wdchar in wdchars)
{
int v = Convert.ToInt32(wdchar); //先轉成整數
if (v > 255) //有二個 bytes 組成 char
{
int hv = (int)(v / 256); //高位元轉成整數
int lv = v % 256; //低位元轉成整數
resbyte[ii] = Convert.ToByte(lv); //低位元轉成 byte
resbyte[ii + 1] = Convert.ToByte(hv); //高位元轉成 byte
//轉成16進位字串值,以下兩行可省略
//string hs = Convert.ToString(hv, 16).ToUpper().PadLeft(2, '0');
//string ls = Convert.ToString(lv, 16).ToUpper().PadLeft(2, '0');
ii += 2;
}
else //只有一個 byte 組成 char
{
string ls = Convert.ToString(v, 16).ToUpper().PadLeft(2, '0');
resbyte[ii] = Convert.ToByte(v);
ii++;
}
}
}
後來發現,如果資料庫設定成這樣,就不會發生上面亂碼的問題,但常常的情況是我們不容許改動現有的資料庫校對。
資料庫 utf8_bin
L 資料表 utf8_bin
L有中文的欄位 utf8_bin
原文 2009-12-08 02:18:10