Oracle数据库多语言文字存储解决方案(四)
来源:互联网 发布:矩阵分析引论详细答案 编辑:程序博客网 时间:2024/05/01 02:22
以前面mer_categ为例,修改表结构如下:
字段
数据类型
长度
说明
S_merc_id
Varchar2
20
分类编号
S_merc_name
NVarchar2
50
分类名称
环境参数:
数据库字符集:ZHS16GBK
数据库国家字符集:AL16UTF16
NLS_LANG:ZHS16GBK
测试:
Insert into mer_catag values (‘01’,’삼성’);
验证一下:select dump(s_merc_name,16) from mer_categ
结果是:Typ=1 Len=4: ff,1f,ff,1f
“ff,1f”是全角“?”在UTF-16字符集中的编码,怎么写了两个“?”进去?
查阅官方资料:
You can input Unicodestring literals in SQL and PL/SQL as follows:
Put a prefix N
before a string literal that is enclosed with singlequote marks. This explicitly indicates that the following stringliteral is an NCHAR
string literal. For example, N'résumé'
is an NCHAR
string literal…..
按照官方的说法,在字符串前面加“N”即代表“N”后面跟着的单引号内的字符串是NCHAR字符串。NCHAR字符串是什么?NCHAR意味着字符串将使用数据库的国家字符集进行编码。测试:
Insert into mer_catag values (‘01’,N’삼성’);
验证一下:selectdump(s_merc_name,16) from mer_categ
结果是:Typ=1 Len=4:ff,1f,ff,1f
结果显示数据库存了两个全角大“?”。Why?
前面引用到:
SQL语句提交到Server之前,SQL语句中的字符串部分(不管前面有没有N’)作为语句的一部分将被用NLS_LANG定义的字符集进行编码。
原来在客户端NCHAR字符串(N’삼성’)就被GBK字符集转换了,传到server端的是两个全角“?”。那将客户端NLS_LANG改为AL32UTF8:
数据库字符集:ZHS16GBK
数据库国家字符集:AL16UTF16
NLS_LANG:AL32UTF8
测试:
Insert into mer_catag values (‘01’,N’삼성’);
验证一下:selectdump(s_merc_name,16) from mer_categ
结果是:Typ=1 Len=4:ff,1f,ff,1f
结果显示数据库还是存了两个全角“?”。
再看文档:
When the SQL orPL/SQL statement is transferred from client to the database server,its character set is converted accordingly. It is importantto note that if the database character set does not contain allcharacters used in the text literals, then the data is lost in thisconversion. This problem affectsNCHAR
string literals more than the CHAR
text literals. This is because the N'
literalsare designed to be independent of the database character set, andshould be able to provide any data that the client character setsupports.
难道让我再改数据库字符集为UTF8?!
To avoid data loss in conversion to anincompatible database character set, you can activate the NCHAR
literal replacementfunctionality. The functionality transparently replaces theN'
literals on the client side with an internal format. The database server then decodesthis to Unicode when the statement is executed.
还真复杂,那如何实现NCHAR
literalreplacement?
…
you can set the client environment variableORA_NCHAR_LITERAL_REPLACE
to TRUE
to control the functionality
…
按他说的办,set ORA_NCHAR_LITERAL_REPLACE=TRUE
再测:
Insert into mer_catag values (‘01’,N’삼성’);
验证一下:select dump(s_merc_name,16) from mer_categ
结果是:Typ=1 Len=4: c0,bc,c1,31
终于成功了!字符串:N’삼성’被替换成什么样的internalformat,数据库又怎么将其解码成Unicode,我们不得而知,只是按照官方的方法去做将多国文字正确地写入数据库中。这时的环境参数是:
服务器端:
数据库字符集:ZHS16GBK
数据库国家字符集:AL16UTF16
客户端:
NLS_LANG:AL32UTF8
环境变量:ORA_NCHAR_LITERAL_REPLACE =TRUE
这样的字符集设置,改变了客户端NLS_LANG与环境变量。如果不改变任何默认设置,比如客户端NLS_LANG仍然是ZHS16GBK,也不要什么环境变量设置,那可以实现多国文字的正确存储吗?如果你使用VB.NET开发,试试下面的代码:
………………
Dim conn AsNewSystem.Data.OracleClient.OracleConnection("database conn string")
Dim cmd AsNewSystem.Data.OracleClient.OracleCommand("insert Into mer_categ(S_merc_name )Values(:S_merc_name)", conn)
cmd.Parameters.Add("S_merc_name",OracleClient.OracleType.NVarChar).Value = "삼성" conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
……………
运行结果一定让你满意。为什么通过设置command参数的形式就可以直接正确地写到数据库中,后台的处理机制还是不得而知,但我的猜测是将字符用数据库国家字符集的Unicode编码直接传到OracleServer,而不需经过字符集的任何转换。
参考资料:
Oracle® Database Globalization SupportGuide
10g Release 2 (10.2)
7 Programmingwith Unicode
http://download-east.oracle.com/docs/cd/B19306_01/server.102/b14225/ch7progrunicode.htm#CACHHIFE
- Oracle数据库多语言文字存储解决方案(四)
- Oracle数据库多语言文字存储解决方案(四)
- Oracle数据库多语言文字存储解决方案
- Oracle数据库多语言文字存储解决方案(一)
- Oracle数据库多语言文字存储解决方案(二)
- Oracle数据库多语言文字存储解决方案(三)
- oracle数据库(四)
- Oracle数据库(四)多行函数
- 十六、基础教程-语言文字(lang)
- Oracle数据库基础(四)--视图,序列,存储过程
- 日志数据库存储解决方案
- 数据库存储图片解决方案
- ORACLE存储过程(四)之游标
- Oracle 数据库安全性解决方案
- oracle 数据库乱码解决方案
- oracle数据库学习笔记(四)
- Oracle数据库学习(四)--高级查询
- Oracle数据库学习<四>
- ASP.NET操作Word文档收藏
- VC编程中关于新建的框架窗口的销毁的一个心得
- ADSL拨号,VMWare的Guest客户机上网设置
- 【GDI绘图】防止闪烁
- SWT、Swing 或 AWT:哪个更适合您?
- Oracle数据库多语言文字存储解决方案(四)
- 对SWT控件的拖放深入了解
- 如何展开有效的业务讲座
- 好人陈虻
- 软件加密锁原理
- HTML Table的几个样式
- 再谈oracle服务器内存(SGA+PGA+OS)设置
- sqlserver一些入门的知识
- 关于oracle sga设置的总结