Oracle中NLS_NCHAR_CHARACTERSET和NLS_CHARACTERSET之间的区别是什么?

14

我想知道在Oracle中NLS_NCHAR_CHARACTERSETNLS_CHARACTERSET设置之间的区别。

据我所知,NLS_NCHAR_CHARACTERSET用于NVARCHAR数据类型,而NLS_CHARACTERSET用于VARCHAR2数据类型。

我尝试在我的开发服务器上测试此设置,我的当前CHARACTERSET设置如下:

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               US7ASCII

然后我将一些中文字符值插入到数据库中。我将这些字符插入到名为data_<seqno>的表中,并更新了VARCHAR2列的ADDRESSADDRESS_2列。根据我对当前设置的NLS_CHARACTERSETUS7ASCII的了解,应该不支持中文字符,但它仍然显示在数据库中。是否NLS_NCHAR_CHARACTERSET优先于此设置?

谢谢。


2
不应复制屏幕截图。请复制/粘贴 SQL Plus 中的文本并格式化代码。 - Wernfried Domscheit
好的,已注意。谢谢指出 :) - Steven Tang Ti Khoon
1个回答

13
总的来说,你提出的所有观点都是正确的。 NLS_NCHAR_CHARACTERSET定义了NVARCHAR2等列的字符集,而NLS_CHARACTERSET用于VARCHAR2

为什么使用US7ASCII也能看到中文字符呢?

原因在于,你的数据库字符集和客户端字符集(即请参阅NLS_LANG值)都是US7ASCII。你的数据库使用US7ASCII,并且它“认为”客户端也使用US7ASCII发送数据。因此,它不会对字符串进行任何转换,数据会以比特位的形式从客户端传输到服务器,反之亦然。
由于这个事实,你可以使用实际上不受US7ASCII支持的字符。请注意,在客户端使用不同的字符集时(例如,当你在Windows应用程序中使用ODP.NET Managed Driver时),数据将变成垃圾!还要注意,如果考虑数据库字符集迁移,你将面临同样的问题。
另一个需要注意的地方是:我不认为你会在其他字符集上得到相同的行为,例如,如果你的数据库和客户端都使用WE8ISO8859P1。同时,请注意,你实际上配置错误。你的数据库使用字符集US7ASCII,你的NLS_LANG值也是US7ASCII(很可能根本没有设置,Oracle默认为US7ASCII),但是SQL*Plus的实际字符集,或者你的cmd.exe终端很可能是CP950CP936。如果您想正确设置所有内容,可以设置环境变量NLS_LANG=.ZHT16MSWIN950(Oracle似乎不支持CP936),或在运行sqlplus.exe之前使用命令chcp 437更改代码页。通过这些适当的设置,您将不会看到任何中文字符,正如您可能预期的那样。

谢谢解释 =) 。我想我懂了 嘿嘿 ;) - Steven Tang Ti Khoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接