脚本报错 ORA-01756:问题出在 NLS_LANG 字符集
2026-10-22 06:50 AlfredZhao 阅读(47) 评论(0) 收藏 举报在 sqlplus 执行脚本时,笔者遇到过一个容易误判的报错:ORA-01756: quoted string not properly terminated。表面看像 SQL 引号写错了,实际却是客户环境的变量设置有问题。下面用一次复现实验说明原因。
01 | 故障复现
先按客户环境的设置,把 NLS_LANG 指定为 GBK 字符集:
$ export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
进入 sqlplus 后执行一条包含中文的查询:
SQL> SELECT '通用智能体' FROM dual;
ERROR:
ORA-01756: quoted string not properly terminated
SQL 本身没有引号问题,却报了“引号未正确结束”。退出后把变量改为 UTF-8:
$ export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
再次执行同一条语句,结果正常返回:
SQL> SELECT '通用智能体' FROM dual;
'通用智能体'
---------------
通用智能体
在终端实际编码为 UTF-8(可通过 locale 确认)的前提下,同一个终端、同一条 SQL,只改了 NLS_LANG,结果完全不同。这说明 sqlplus 对客户端字符集与终端编码是否一致非常敏感。
02 | NLS_LANG 是什么
NLS_LANG 是 Oracle 客户端工具(如 sqlplus、sqlcl、expdp 等)的重要环境变量,用于定义客户端的语言、地域和字符集,标准格式为:
语言_地域.字符集
例如 AMERICAN_AMERICA.AL32UTF8。
其中字符集部分用于声明客户端侧的字符集,客户端工具会据此在终端输入输出与数据库字符集之间做转换。实践中应让它与终端实际编码保持一致,否则容易出现乱码或解析异常。
03 | 为什么会出现引号错误
关键在于字符集是否与终端实际编码一致。
在 Linux 环境下,终端编码可通过 locale 查看,常见为 UTF-8。若终端确为 UTF-8 而 NLS_LANG 被设为 ZHS16GBK,sqlplus 会按 GBK 规则去解析 UTF-8 字节流。中文字符是多字节的,编码规则不一致就会导致字节错位,连单引号的边界都可能识别失败,最终抛出 ORA-01756。
所以这个报错并不一定是 SQL 写错了,也可能是客户端字符集与终端编码不匹配。
04 | 传统工具与现代工具的差异
传统 sqlplus 底层是 C/C++,对编码高度敏感、缺乏容错,一旦设置不一致就容易出问题。
而现代的 sql / SQLcl 基于 Java 运行,在部分场景下对输入流的处理更宽容。但在 NLS_LANG 与终端编码不一致时,其行为仍取决于具体版本和运行环境,建议以所用版本的官方文档和实际测试结果为准。
05 | 实践建议
在 Linux 环境下做日常运维和编写自动化脚本时,建议统一显式设置:
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
让客户端字符集与终端编码保持一致,有助于减少 sqlplus、expdp/impdp 等工具的编码问题。实际设置时还需结合数据库字符集和终端编码确认,避免在非 UTF-8 环境中直接套用。
关注我,和AI一起成长~
转载请注明原文链接:https://www.cnblogs.com/jyzhao/p/23394972
👋 感谢阅读,欢迎关注我的公众号 「赵靖宇」
浙公网安备 33010602011771号