SQL*Plus 执行中文 SQL 文件,如何避开乱码坑
2026/7/22 10:20:14 网站建设 项目流程

先看清三个关键角色
执行 SQL 文件时,至少涉及三处字符集:

Linux Locale:由 LANG 或 LC_CTYPE 控制,影响 Shell 如何处理文本。
SQL*Plus 客户端字符集:由 NLS_LANG 控制。
SQL 文件实际编码:常见是 UTF-8 或 GBK。
核心原则很简单:

SQL 文件编码要和 NLS_LANG 对应的客户端字符集一致,再由 Oracle 负责客户端与数据库之间的字符集转换。

这里最容易误解的是:NLS_LANG 表示客户端字符集,不是数据库字符集。

02 | UTF-8 文件的推荐配置
大多数 Linux 环境和编辑器默认已经使用 UTF-8,因此更推荐统一使用 UTF-8。

export LANG=en_US.UTF-8
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
如果使用中文 Locale,也可以是:

export LANG=zh_CN.UTF-8
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8
SQL 文件建议保存为:

UTF-8
无 BOM,也就是 UTF-8 without BOM
如果 SQL 文件本身是 GBK 编码,才使用:

export LANG=zh_CN.GBK
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
03 | 不要盲目照抄数据库字符集
很多人看到数据库字符集是 ZHS16GBK,就直接设置:

export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
这只有在客户端 SQL 文件本身也是 GBK 编码时才合适。

如果 SQL 文件是 UTF-8,而数据库字符集是 ZHS16GBK,客户端仍然应该按 UTF-8 设置:

export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
此时 Oracle 会完成字符集转换:

UTF-8(客户端)

Oracle Character Conversion

ZHS16GBK(数据库)
所以排查时不要只盯数据库字符集,更要先确认 SQL 文件到底是什么编码。

04 | 如何确认文件和数据库字符集
查看 SQL 文件编码,优先用:

file test.sql
file -i test.sql
如果输出中看到 charset=utf-8,说明是 UTF-8。若显示 UTF-8 Unicode (with BOM),说明文件带 BOM。

也可以用 iconv 验证 UTF-8 是否合法:

iconv -f UTF-8 -t UTF-8 test.sql >/dev/null
echo $?
返回 0 表示合法 UTF-8;如果出现 illegal input sequence,说明不是合法 UTF-8。

检查是否带 BOM:

xxd -l 16 test.sql
如果文件开头出现:

ef bb bf
说明带 BOM。

数据库字符集可以用 SQL 查询:

SELECT value
FROM nls_database_parameters
WHERE parameter = ‘NLS_CHARACTERSET’;
常见结果可能是 AL32UTF8 或 ZHS16GBK。

05 | LC_ALL 不一定要设置
通常不需要刻意设置 LC_ALL。Locale 优先级大致是:

LC_ALL

LC_*

LANG
SQL*Plus 中文乱码更相关的是:

LANG
LC_CTYPE
NLS_LANG
很多环境只设置下面这一项就够了:

export LANG=en_US.UTF-8
LC_ALL 是强制覆盖所有 Locale 设置,并不是解决 SQL*Plus 中文乱码的关键。有些系统还可能没有安装对应 Locale,导致 cannot change locale。可以先确认系统支持项:

locale -a
06 | 一套稳妥排查顺序
遇到乱码时,建议依次执行:

locale
echo $LANG
echo $NLS_LANG
file -i test.sql
再查数据库字符集:

SELECT value
FROM nls_database_parameters
WHERE parameter=‘NLS_CHARACTERSET’;

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询