Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > SQL*Plus中文乱码解决

Linux下用SQL*Plus执行中文SQL文件时如何避开乱码坑

作者:AlfredZhao

在Linux上用sqlplus执行.sql文件时,中文注释或字符串显示乱码怎么办?本文帮你理清SQL文件编码、NLS_LANG和Linux Locale三者的关系,提供一套稳妥的排查顺序,让你彻底告别SQL*Plus中文乱码的烦恼

在 Linux 上用 sqlplus @xxx.sql 执行脚本时,只要 SQL 文件里有中文字符串或中文注释,就可能遇到乱码。这个问题通常不是数据库本身坏了,而是 SQL 文件编码、Linux Locale、SQL*Plus 客户端字符集没有对齐。

先看清三个关键角色

执行 SQL 文件时,至少涉及三处字符集:

核心原则很简单:

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

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

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 文件建议保存为:

如果 SQL 文件本身是 GBK 编码,才使用:

export LANG=zh_CN.GBK
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

不要盲目照抄数据库字符集

很多人看到数据库字符集是 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 文件到底是什么编码。

如何确认文件和数据库字符集

查看 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';

常见结果可能是 AL32UTF8ZHS16GBK

LC_ALL 不一定要设置

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

LC_ALL
↓
LC_*
↓
LANG

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

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

export LANG=en_US.UTF-8

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

locale -a

一套稳妥排查顺序

遇到乱码时,建议依次执行:

locale
echo $LANG
echo $NLS_LANG
file -i test.sql

再查数据库字符集:

SELECT value
FROM nls_database_parameters
WHERE parameter='NLS_CHARACTERSET';

笔者更推荐的长期做法是:团队统一使用 UTF-8 无 BOM 的 .sql 文件,并配置:

export LANG=en_US.UTF-8
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8

这样可以减少 UTF-8、GBK 混用带来的跨平台问题。

一句话总结:保持 SQL 文件编码、Linux Locale 和 NLS_LANG 一致,让 Oracle 负责客户端与数据库之间的字符集转换,是避免 SQL*Plus 中文乱码的稳妥方案。

到此这篇关于Linux下用SQL*Plus执行中文SQL文件时如何避开乱码坑的文章就介绍到这了,更多相关SQL*Plus中文乱码解决内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文