sql*plus乱码主因是nls_lang与数据库字符集不匹配,需同步校准数据库字符集(查nls_database_parameters)、nls_lang声明及终端编码三者,缺一不可。
nls_lang 环境变量与数据库字符集不匹配,是 sql*plus 出现乱码的最常见原因。 它不是终端显示问题、不是 oracle 安装缺陷,而是客户端语言/字符集声明和实际数据库底层编码之间对不上号。只要两边不一致,中文提示、错误信息、查询结果里的汉字就大概率变成 ???? 或方块。
查清数据库实际字符集用 SELECT * FROM NLS_DATABASE_PARAMETERS
别猜,直接查库:
SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET'; VALUE ------------------------------ AL32UTF8
或
SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_LANGUAGE'; VALUE ------------------------------ SIMPLIFIED CHINESE
关键字段只有两个:NLS_CHARACTERSET(决定能存什么字、怎么存)和 NLS_LANGUAGE(决定报错/提示用哪种语言)。常见组合有:
-
AL32UTF8(Oracle 推荐的 UTF-8 变体)→ 对应NLS_LANG中后半段应为.AL32UTF8 -
ZHS16GBK(Windows/老系统常用)→ 对应.ZHS16GBK -
US7ASCII(纯英文库)→ 不该存中文,设.US7ASCII也无意义,应避免
Linux 下设置 NLS_LANG 必须写进 ~/.bash_profile
临时 export 无效——SQL*Plus 启动时只读一次环境变量,且子 shell 不继承父 shell 的 export(尤其当你用 su - oracle 切换用户时)。
在 Oracle 用户家目录下编辑:
vi ~/.bash_profile
追加一行(按你查到的数据库字符集选):
- 若库是
AL32UTF8:export NLS_LANG="AMERICAN_AMERICA.AL32UTF8" - 若库是
ZHS16GBK:export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
然后必须执行:
source ~/.bash_profile
再运行 sqlplus / as sysdba 才生效。漏掉 source 是高频失误点。
SecureCRT 或其他终端需同步匹配系统 LANG
NLS_LANG 解决的是 Oracle 客户端协议层的编码声明,但终端本身还得能渲染这些字节。如果 LANG=zh_CN.UTF-8,而 CRT 的 Character encoding 设成 ISO-8859-1,照样显示 ???。
检查当前系统语言:
echo $LANG
对应设置终端:
-
LANG=zh_CN.UTF-8→ CRT 中选UTF-8 -
LANG=zh_CN.GB18030→ CRT 中选GB18030或GBK
注意:NLS_LANG 和终端编码不必完全相同(比如 NLS_LANG=.AL32UTF8 + 终端 UTF-8 是安全组合),但不能出现“声明 UTF-8 却让终端用 GBK 解码”这种硬冲突。
真正麻烦的不是配置项本身,而是这三者要同时对齐:数据库字符集、NLS_LANG 声明、终端渲染编码。少对一环,乱码就回来——而且错误提示(如 ORA-01102)本身也是由 NLS_LANG 控制显示语言的,所以乱码时你甚至看不到准确的报错原文。











