伺服器端字符集固定為 AMERICAN_AMERICA.WE8ISO8859P1(西歐字符集,對應 .NET 的 iso-8859-1),無權修改伺服器設定。客戶端嘗試各種字符集均出現亂碼。
將客戶端 NLS_LANG 同樣設為 AMERICAN_AMERICA.WE8ISO8859P1,使 Oracle 不進行字符集轉換,原始位元組直接傳遞到應用層;再在程式碼中將 iso-8859-1 位元組陣列轉為 GB2312(或 UTF-8)字串。
/// <summary>
/// 將西歐字符集 (ISO-8859-1) 位元組轉為 GB2312 字串
/// </summary>
public static string Convert8859P1ToGB2312(string s)
{
if (string.IsNullOrEmpty(s)) return s;
// 1. 先用 ISO-8859-1 解碼回位元組陣列(還原資料庫實際存儲的原始位元組)
byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(s);
// 2. 再用 GB2312 解碼為正確中文字串
return Encoding.GetEncoding("gb2312").GetString(bytes);
}
NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1NLS_LANG 決定。Encoding.UTF8。此法適用於「伺服器字符集不可變、客戶端可控、應用層可插入轉碼邏輯」的場景;若可修改伺服器字符集為 AL32UTF8 或 ZHS16GBK,則為更根治方案。