使用正确的字符集将字符写入数据库

本文关键字:字符 数据库 字符集 | 更新日期: 2023-09-27 18:10:09

我在将汉字写入Oracle数据库时遇到了一个问题。这里有一些信息供您参考。

  1. 环境:Oracle 8

    select userenv('language') form dual;
    

    返回

    American.America.UTF8
    
  2. 开发:

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

    gb2312
    

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

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中的值是不对的,无论是值还是它的转储结果。

使用正确的字符集将字符写入数据库

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

看看维基百科,我们看到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=所有#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.