oracle-databasecharacter-encodingasciiutfvarchar2

difference between NLS_NCHAR_CHARACTERSET and NLS_CHARACTERSET for Oracle


I would like to know the difference between NLS_NCHAR_CHARACTERSET and NLS_CHARACTERSET settings in Oracle?

From my understanding, NLS_NCHAR_CHARACTERSET is for NVARCHAR data types and for NLS_CHARACTERSET would be for VARCHAR2 data types.

I tried to test this on my development server which my current settings for CHARACTERSET are as the following :

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

Then I inserted some Chinese character values into the database. I inserted the characters into a table called data_<seqno> and updated the column for ADDRESS and ADDRESS_2 which are VARCHAR2 columns. Right from my understanding with the current setting for NLS_CHARACTERSET US7ASCII, Chinese characters should not be supported but it is still showing in the database. Does NLS_NCHAR_CHARACTERSET take precedence over this?

Thank You.


Solution

  • In general all your points are correct. NLS_NCHAR_CHARACTERSET defines the character set for NVARCHAR2, et. al. columns whereas NLS_CHARACTERSET is used for VARCHAR2.

    Why is it possible that you see Chinese characters with US7ASCII?

    The reason is, your database character set and your client character set (i.e. see NLS_LANG value) are both US7ASCII. Your database uses US7ASCII and it "thinks" also the client sends data using US7ASCII. Thus it does not make any conversion of the strings, the data are transferred bit-by-bit from client to server and vice versa.

    Due to that fact you can use characters which are actually not supported by US7ASCII. Be aware, in case your client uses a different character set (e.g. when you use ODP.NET Managed Driver in an Windows application) the data will be rubbish! Also if you would consider a database character set migration you have the same issue.

    Another note: I don't think you would get the same behavior with other character sets, e.g. if your database and your client both would use WE8ISO8859P1 for example. Also be aware that you actually have wrong configuration. Your database uses character set US7ASCII, your NLS_LANG value is also US7ASCII (most likely it is not set at all and Oracle defaults it to US7ASCII) but the real character set of SQL*Plus, resp. your cmd.exe terminal is most likely CP950 or CP936.

    If you like to set everything properly you can either set your environment variable NLS_LANG=.ZHT16MSWIN950 (CP936 seems to be not supported by Oracle) or change your codepage before running sqlplus.exe with command chcp 437. With this proper settings you will not see any Chinese characters as you probably would have expected.