使用正确的字符集将字符写入DB

时间:2011-10-02 06:48:27

标签: c# oracle

我遇到了将中文字符写入Oracle数据库的问题。以下是一些供您参考的信息。

  1. 环境:Oracle 8

    select userenv('language') form dual;
    

    返回

    American.America.UTF8
    
  2. 开发:

    .NET2/C#
    
  3. 客户端字符集:

    gb2312
    
  4. 我只是手动将写入值测试到表中,结果是正确的,应该如下所示:

    VALUE: 朋友        //chinese word means 'friend'
    DUMP: 197,243,211,209 //caculated by Oracle dump() function
    

    使用代码编写,代码捕捉如下:

    Encoding def = Encoding.Default;
    Encoding utf8 = Encoding.UTF8;
    byte[] bytes = def.GetBytes("朋友");
    //For debug
    //string debug = "";
    //foreach(byte b in bytes)
    //   debug += b.ToString() + " ";
    //Debug.WriteLine(debug); //That will display 197,243,211,209 as the same as the Dump value mentioned
    string value = utf8.GetString(bytes);
    //I also try, string value = utf8.GetString(Encoding.Convert(def,utf8,bytes))
    string sql = String.Format("UPDATE T SET C='{0}' WHERE...",value);
    //execute the sql...
    

    之后,存储在DBMS中的值不正确,包括值和转储结果。

1 个答案:

答案 0 :(得分:1)

Decimal Hexadecimal Binary
197     c5          1100 0101
243     f3          1111 0011
211     d3          1101 0011
209     d1          1101 0001

Wikipedia我们看到197是双字节序列的第一个字节,243是四字节序列的第一个字节,211是两个字节序列的第一个字节,208是第一个字节两个字节序列的字节。这不是有效的UTF-8。你能告诉我们朋友的两个角色的unicode代码点是什么吗?

编辑啊,GB2313,c5f3是Unicode代码点u + 670b。并且d3d1是u + 53cb。 (使用转换器http://demo.icu-project.org/icu-bin/convexp?conv=ibm-1383_P110-1999&ShowLocales&s=ALL#ShowLocales

找到

仔细检查Oracle客户端正在使用的客户端字符集。我所看到的(在Oracle 10gR2上)是,如果Oracle的客户端具有与数据库服务器相同的字符编码,则不会翻译字符(因为它们是相同的字符集),但它们不会被验证。在手动插入时似乎它们是相同的,并且为所需的字符插入了GB2313值,这在DB内是无效的,因为它是utf8。

注意,Oracle的“utf8”字符集不是完整的现代UTF-8,而是CESU-8。在这种情况下不是问题,因为这些字符位于基本多语言平面上,并且在UTF-8和CESU-8中具有相同的编码。我能找到的最早的参考资料是Oracle 8i:http://download.oracle.com/docs/cd/A87860_01/doc/server.817/a76966/appa.htm#971460