Oracle设置了默认的NLS_LANG

我在RHEL6上运行Oracle数据库11g。 如果没有客户端NLS_LANG设置某个utf8字符的长度是2.在设置了NLS_LANG = AMERICAN_AMERICA.UTF8之后,长度只有1.怎么样可以打赌整个数据库的默认NLG_LANG改变了? 我不想只为会话更改此值,或者像linux中的环境variables。 有没有可能将其设置为一般的数据库?

SQL> select length('á') from dual; LENGTH('??') ------------ 2 # export NLS_LANG=AMERICAN_AMERICA.UTF8 SQL> select length('á') from dual; LENGTH('á') ----------- 1 

非常感谢您的任何想法

Solutions Collecting From Web of "Oracle设置了默认的NLS_LANG"

这是可能发生的事情:

  • 您的客户端字符集必须是像CP1252或ISO-8859-15,而事实上,您的客户端真的使用UTF8。
  • 在这个字符集(UTF8)中,符号á需要两个字节,所以您的客户端发送这两个字节,同时告诉Oracle将它们视为CP1252。 在CP1252中,两个字节代码为两个字符,导致DB将输入解释为两个字符,因此length('à')等于2(如果插入此字符串,插入的结果不等于à
  • 当你正确设置字符集时,输入被oracle正确处理为单个字符,其长度为1(仍然是两个字节)。

结论:正确设置你的客户端字符集,否则你会得到翻译错误(你不会以这种方式得到非法字符,但你可能会得到奇怪的符号( ¿ )。

数据库字符集在创建时设置,通常通过导出/创建空白数据库/导入进行更改。

由于数据库字符集是AL32UTF8,因此当您将客户端NLS_LANG设置为UTF8时,您告诉Oracle绕过通常在客户端和服务器之间传输数据时发生的字符集转换。 这是非常危险的,因为这意味着如果客户端以任何其他编码方式发送数据,存在无效数据存储在数据库中的相当大的风险。 在这种情况下,返回1的LENGTH调用将错误地编码的数据发送到数据库。 客户机操作系统很可能使用类似ISO-8859-1字符集的数据来表示数据,其中á是单字节字符(二进制值0xE1)。 当客户端发送数据到数据库时,它正在发送0xE1并告诉数据库“相信我,这是有效的UTF-8数据”。 数据库不费心检查二进制数据,注意0xE1不是UTF-8字符集中任何字符的有效二进制表示。 但是现在,如果其他客户端出现,并且正确配置了并且要求进行字符集转换,并且数据库中某个列中存储了0xE1,则字符集转换代码将运行,从而确定0xE1不是有效的UTF-8字符,并将替换字符(通常是'?')而不是á返回给正确配置的客户端。

由于数据库字符集是UTF-8,因此您会期望“á”字符的长度为2. UTF-8是可变宽度字符集。 作为US7ASCII字符集一部分的字符用1字节表示,大多数西欧字符如'á'用2字节表示,大多数亚洲字符用3字节表示。 有一些罕见的字符需要4个字节。

您的NLS_LANG需要设置为与客户端系统支持的字符集匹配。 很少有一个客户端系统具有原生的UTF-8支持。 由于您的客户端设置将覆盖在数据库级别设置的任何内容,这意味着每个客户端都需要配置为设置适当的环境变量。 NLS_LANG FAQ关于如何确定Unix客户端的正确NLS_LANG设置的部分 。