我们有一个Oracle数据库,里面有很多记录。最近我们注意到我们无法在数据类型为nvarchar2的列中保存波斯语/阿拉伯数字,而不是显示问号“?”的数字。
我使用这些命令检查了charset:
SELECT *
from NLS_DATABASE_PARAMETERS
WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
和这个命令
SELECT USERENV('language') FROM DUAL;
我也发出这个命令:
SELECT DUMP(myColumn, 1016) FROM myTable;
结果是这样的:
Typ=1 Len=22 CharacterSet=AL16UTF16: 6,33,6,44,6,27,6,45,0,20,0,3f,0,3f,0,2f,0,3f,0,2f,0,3f
结果似乎没问题但不幸的是我们仍然无法保存该列中的任何波斯语/阿拉伯数字。但波斯语/阿拉伯语字母表还可以。你知道这个问题的原因是什么吗?
谢谢
USERENV('language')
不会返回您的客户端字符集。
所以,SELECT USERENV('language') FROM DUAL;
等于
SELECT l.value||'_'||t.value||'.'||c.value
FROM (SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_LANGUAGE') l
CROSS JOIN (SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_TERRITORY') t
CROSS JOIN (SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET') c;
不可能通过任何SQL语句获取客户端NLS_LANG
(虽然似乎有一个奇怪的解决方法:How do I check the NLS_LANG of the client?)
检查您的客户NLS_LANG
设置。它由Registry(HKLM\SOFTWARE\ORACLE\KEY_%ORACLE_HOME_NAME%\NLS_LANG
,resp.HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_%ORACLE_HOME_NAME%\NLS_LANG
)或环境变量定义。 Environment变量优先。
然后,您必须确保您的客户端应用程序(您没有告诉我们您使用的是哪个)使用与NLS_LANG
中指定的相同的字符集。
如果您的应用程序在Java上运行,请查看:Database JDBC Developer's Guide - Globalization Support
帮自己一个忙,并将数据库的主要字符集从AR8MSWIN1256
转换为AL32UTF8
。大多数这些问题都会消失。你可以忘记NCHAR
和NVARCHAR2
。它们不再需要了。
这是一次性的努力,将偿还一千倍。
有关说明,请参阅Character Set Migration。