连接Oracle9i,因字符集造成乱码的解决方法
我们的系统连的是Oracle10g的库,现在做第三方接口,要连Oracle 9i,但那边的库跟我们的库不是同一种字符集,就造成了乱码问题,据说装9i客户端,通过9i的客户端连9i数据库就可以显示中文,在Dephi里面是这样做的,用的Provider=OraOLEDB.Oracle.1,显示中文没问题,但在C#里面这种方式却还是乱码,估计是跟编程语言有关,C#是托管的,运行在.net framework上。
为了这问题头都大了,在网上找遍了方法,有改环境变量的,有改注册表的,结果还是不行,今天打听到一个可行的办法,如果不考虑性能问题的话,即在Oracle里面用select rawtohex(UTL_RAW.cast_to_raw(trim(字段名))) from 表 把中文转换成16进制,再在C#里面把16进制转换成中文就搞定了。C#的转换函数如下:
View Code
1 /// <summary> 2 /// 从汉字转换到16进制 3 /// </summary> 4 /// <param name="s"></param> 5 /// <returns></returns> 6 public static string GetHexFromChs(string s) 7 { 8 if ((s.Length % 2) != 0) 9 { 10 s += " ";//空格 11 //throw new ArgumentException("s is not valid chinese string!"); 12 } 13 14 System.Text.Encoding chs = System.Text.Encoding.GetEncoding("gb2312"); 15 16 byte[] bytes = chs.GetBytes(s); 17 18 string str = ""; 19 20 for (int i = 0; i < bytes.Length; i++) 21 { 22 str += string.Format("{0:X}", bytes[i]); 23 } 24 25 return str; 26 } 27 /// <summary> 28 /// 从16进制转换成汉字 29 /// </summary> 30 /// <param name="hex"></param> 31 /// <returns></returns> 32 public static string GetChsFromHex(string hex) 33 { 34 if (hex == null) 35 throw new ArgumentNullException("hex"); 36 if (hex.Length % 2 != 0) 37 { 38 hex += "20";//空格 39 //throw new ArgumentException("hex is not a valid number!", "hex"); 40 } 41 // 需要将 hex 转换成 byte 数组。 42 byte[] bytes = new byte[hex.Length / 2]; 43 44 for (int i = 0; i < bytes.Length; i++) 45 { 46 try 47 { 48 // 每两个字符是一个 byte。 49 bytes[i] = byte.Parse(hex.Substring(i * 2, 2), 50 System.Globalization.NumberStyles.HexNumber); 51 } 52 catch 53 { 54 // Rethrow an exception with custom message. 55 throw new ArgumentException("hex is not a valid hex number!", "hex"); 56 } 57 } 58 59 // 获得 GB2312,Chinese Simplified。 60 System.Text.Encoding chs = System.Text.Encoding.GetEncoding("gb2312"); 61 62 63 return chs.GetString(bytes); 64 }