我遇到了将中文字符写入Oracle数据库的问题.以下是一些供您参考的信息.
环境:Oracle 8
select userenv('language') form dual;
Run Code Online (Sandbox Code Playgroud)
回报
American.America.UTF8
Run Code Online (Sandbox Code Playgroud)发展:
.NET2/C#
Run Code Online (Sandbox Code Playgroud)客户端字符集:
gb2312
Run Code Online (Sandbox Code Playgroud)我只是手动将写入值测试到表中,结果是正确的,应该如下所示:
VALUE: ?? //chinese word means 'friend'
DUMP: 197,243,211,209 //caculated by Oracle dump() function
Run Code Online (Sandbox Code Playgroud)
使用代码编写,代码捕捉如下:
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...
Run Code Online (Sandbox Code Playgroud)
之后,存储在DBMS中的值不正确,值和它的转储结果.
Decimal Hexadecimal Binary\n197 c5 1100 0101\n243 f3 1111 0011\n211 d3 1101 0011\n209 d1 1101 0001\nRun Code Online (Sandbox Code Playgroud)\n\n查看维基百科,我们看到 197 是两字节序列的第一个字节,243 是四字节序列的第一个字节,211 是两字节序列的第一个字节,208 是两字节序列的第一个字节。这不是有效的 UTF-8。您能告诉我们两个字符 \xe6\x9c\x8b\xe5\x8f\x8b 的 unicode 代码点是什么吗?
\n\n编辑啊,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找到)
\n\n仔细检查 Oracle 客户端正在使用的客户端字符集。我所看到的(在Oracle 10gR2上)是,如果Oracle的客户端与数据库服务器具有相同的字符编码,那么字符将不会被翻译(因为它们是相同的字符集),但它们不会被验证。看来它们在手动插入时是相同的,并且为您想要的字符插入了 GB2313 值,这在数据库内无效,因为它是 utf8。
\n\n请注意,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。
\n