必须先查数据库字符集再配NLS_LANG,执行SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET'获取真实值,常见为ZHS16GBK、AL32UTF8或UTF8,切勿混淆NLS_NCHAR_CHARACTERSET。

查清数据库字符集再配NLS_LANG
不先确认数据库用的什么字符集,直接设 NLS_LANG 就是碰运气。执行这条 SQL 获取真实值:
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET';
常见返回:ZHS16GBK(Windows 中文环境)、AL32UTF8(Linux/云上主流)、UTF8(旧版,已不推荐)。注意别查 NLS_NCHAR_CHARACTERSET,那是给 NVARCHAR2 用的,和普通字段无关。
Windows 命令行下 set NLS_LANG 必须三段齐全
CMD 默认代码页是 936(即 GBK),但很多人设成 AL32UTF8,结果字节流被错误解码,中文全变问号或方块。
-
NLS_LANG格式严格为LANGUAGE_TERRITORY.CHARACTERSET,缺一不可、顺序不能乱 - 正确示例:
AMERICAN_AMERICA.ZHS16GBK或SIMPLIFIED CHINESE_CHINA.ZHS16GBK(空格允许,但别加引号) - 错误写法:
ZHS16GBK、AMERICAN.ZHS16GBK、AMERICAN_AMERICA.AL32UTF8(CMD 用 GBK 终端却配 UTF-8 字符集)——Oracle 直接忽略该变量 - 临时生效:在启动
sqlplus前执行set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK;永久设置要改系统环境变量,且必须重启 CMD 才加载
PL/SQL Developer 等 GUI 工具会覆盖系统级 NLS_LANG
很多用户设了系统环境变量,但 PL/SQL Developer 启动后中文仍乱码,是因为它有自己的配置入口,优先级更高:
- 菜单栏 → 工具 → 首选项 → Oracle → 连接 → 语言,填的值会直接覆盖系统
NLS_LANG - 如果用了 Instant Client 启动(比如
plsqldev.bat),还要检查脚本里是否硬编码了set NLS_LANG=...,这个值也会覆盖注册表和系统变量 - 注册表路径
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1\NLS_LANG只对 GUI 工具生效,命令行不读这里
Java/Python 应用根本不用 NLS_LANG
NLS_LANG 对 JDBC 和 cx_Oracle/oracledb 完全无效,它们不读这个环境变量。
- Java 必须在 JDBC URL 显式指定字符集,例如:
jdbc:oracle:thin:@host:1521:orcl?useUnicode=true&characterEncoding=UTF-8(对应AL32UTF8数据库) - Python 的
cx_Oracle或新版oracledb也需在连接参数中指定:encoding='UTF-8'、nencoding='UTF-8' - 验证是否生效不能只看环境变量,连上后必须查:
SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER IN ('NLS_LANGUAGE', 'NLS_TERRITORY', 'NLS_CHARACTERSET');,重点比对返回的NLS_CHARACTERSET是否匹配数据库值
最常被忽略的是:设完不验证,等于白设;不同工具读取 NLS_LANG 的路径和优先级完全不同,不能靠一个设置“一劳永逸”。


















