当前位置: 代码网 > it编程>数据库>MsSqlserver > Linux下用SQL*Plus执行中文SQL文件时如何避开乱码坑

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

2026年07月16日 MsSqlserver 我要评论
在 linux 上用 sqlplus @xxx.sql 执行脚本时,只要 sql 文件里有中文字符串或中文注释,就可能遇到乱码。这个问题通常不是数据库本身坏了,而是 sql 文件编码、linux lo

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

先看清三个关键角色

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

  • linux locale:由 langlc_ctype 控制,影响 shell 如何处理文本。
  • sql*plus 客户端字符集:由 nls_lang 控制。
  • sql 文件实际编码:常见是 utf-8 或 gbk。

核心原则很简单:

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

  • utf-8
  • 无 bom,也就是 utf-8 without bom

如果 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 中文乱码更相关的是:

  • lang
  • lc_ctype
  • nls_lang

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

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中文乱码解决内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com