oracle存储藏语,Oracle数据库多语言文字存储解决方案(续)

以前面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 Unicode string literals in SQL and PL/SQL as

follows:

Put a prefixNbefore a string literal that is enclosed with

single quote marks. This explicitly indicates that the following

string literal is anNCHARstring literal. For example,N'résumé'is anNCHARstring literal…..

按照官方的说法,在字符串前面加“N”即代表“N”后面跟着的单引号内的字符串是NCHAR字符串。NCHAR字符串是什么?NCHAR意味着字符串将使用数据库的国家字符集进行编码。测试:

Insert into mer_catag values (‘01’,N’삼성’);

验证一下:select dump(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’삼성’);

验证一下:select dump(s_merc_name,16) from

mer_categ

结果是:Typ=1 Len=4: ff,1f,ff,1f

结果显示数据库还是存了两个全角“?”。

再看文档:

When the SQL or

PL/SQL statement is transferred from client to the database server,

its character set is converted accordingly.It is important to note that if the

database character set does not contain all characters used in the

text literals, then the data is lost in this

conversion.This problem

affectsNCHARstring literals more than

theCHARtext literals. This is

because theN'literals are designed to be independent

of the database character set, and should be able to provide any

data that the client character set supports.

难道让我再改数据库字符集为UTF8?!

To avoid data loss

in conversion to an incompatible database character set, you can

activatetheNCHARliteral replacement

functionality. The

functionality transparently replaces

theN'literals on the client side with

aninternalformat. The database server then decodes

this to Unicode when the statement is executed.

还真复杂,那如何实现NCHARliteral

replacement?

you can set the client environment

variableORA_NCHAR_LITERAL_REPLACEtoTRUEto control the functionality

按他说的办,setORA_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’삼성’被替换成什么样的internal format,数据库又怎么将其解码成Unicode,我们不得而知,只是按照官方的方法去做将多国文字正确地写入数据库中。这时的环境参数是:

服务器端:

数据库字符集:ZHS16GBK

数据库国家字符集:AL16UTF16

客户端:

NLS_LANG:AL32UTF8

环境变量:ORA_NCHAR_LITERAL_REPLACE =TRUE

这样的字符集设置,改变了客户端NLS_LANG与环境变量。如果不改变任何默认设置,比如客户端NLS_LANG仍然是ZHS16GBK,也不要什么环境变量设置,那可以实现多国文字的正确存储吗?如果你使用VB.NET开发,试试下面的代码:

………………

DimconnAsNewSystem.Data.OracleClient.OracleConnection("database conn string")

DimcmdAsNewSystem.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编码直接传到Oracle Server,而不需经过字符集的任何转换。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值