pl/sql生成json中文乱码的根本原因是oracle字符集协商失败:数据库必须为al32utf8(非utf8或zhs16gbk),nls_lang环境变量须设为american_america.al32utf8并生效于系统变量,json_object返回clob易触发错误解码,应显式cast为varchar2或使用dbms_output输出,导出文件需勾选“utf-8 with bom”。

PL/SQL 生成 JSON 时中文变成 ????? 或 Unicode 转义(如 \u4f60\u597d),根本不是 JSON 语法问题,而是 Oracle 的字符集协商没走通——JSON_OBJECT、JSON_ARRAY 等函数输出的 CLOB 或 VARCHAR2 值,在客户端解码时被当成了错误字符集。
确认数据库实际字符集是否为 AL32UTF8
Oracle 19c 默认字符集是 AL32UTF8(即 UTF-8),但不能只信“默认”。必须查真实值:
-
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET';—— 返回必须是AL32UTF8,不是UTF8(旧版别名,不等价)或ZHS16GBK -
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');—— 两个都应为AL32UTF8;若NLS_NCHAR_CHARACTERSET是AL16UTF16,不影响 JSON 输出,但需留意NVARCHAR2字段行为
如果查出来不是 AL32UTF8,后续所有客户端配置都白搭——得先评估是否可改库(生产环境慎操作),否则只能靠客户端层补偿。
PL/SQL Developer 中 NLS_LANG 必须匹配且生效
即使数据库是 AL32UTF8,PL/SQL Developer 仍可能用系统 ANSI 代码页(如 GBK)去 decode 返回的字节流,导致中文变 ?????。
- 变量名必须是
NLS_LANG(不是NSL_LANG或其他拼写) - 变量值格式严格为
LANGUAGE_TERRITORY.CHARACTERSET,例如:AMERICAN_AMERICA.AL32UTF8(推荐)或SIMPLIFIEDCHINESE_CHINA.AL32UTF8(注意中间无空格) - 必须设在「系统环境变量」里(非用户变量),否则 PL/SQL Developer 启动时可能读不到
- 设完后彻底关闭 PL/SQL Developer 进程(任务管理器检查
plsqldev.exe是否残留),再重启——仅“重新连接”不够
验证是否生效:打开 PL/SQL Developer → Help → Support Info → 查看 NLS_LANG 行是否显示你刚设置的值。没出现=没生效。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
JSON 函数返回类型影响客户端解码方式
JSON_OBJECT 默认返回 CLOB,而 PL/SQL Developer 对 CLOB 的渲染逻辑和 VARCHAR2 不同——尤其在字段别名、字符串值含中文时,容易触发隐式字符集转换。
- 显式 cast 成
VARCHAR2(32767)再输出,能绕过部分 CLOB 解码路径:CAST(JSON_OBJECT(...) AS VARCHAR2(32767)) - 若用
JSON_OBJECT(... RETURNING CLOB),确保你的 PL/SQL Developer 版本 ≥ 14.0.6(旧版对 UTF-8 CLOB 渲染有缺陷) - 避免在 SQL Worksheet 里直接
SELECT JSON_OBJECT(...) FROM DUAL—— 改用匿名块BEGIN DBMS_OUTPUT.PUT_LINE(...); END;,并开启DBMS_OUTPUT(工具 → Options → Windows → DBMS Output),因为 DBMS_OUTPUT 的编码处理更稳定
注意:DBMS_OUTPUT.PUT_LINE 输出中文乱码?说明 NLS_LANG 没生效或终端编码不对——此时不是 JSON 问题,是基础环境问题。
导出 JSON 文件时额外踩坑点
即使界面显示正常,右键“Export to file”保存的 .json 文件打开仍是乱码,这是 PL/SQL Developer 导出功能默认用系统 ANSI 编码(Windows=GBK),而非 UTF-8。
- 导出时务必勾选 “UTF-8 with BOM”(不是“UTF-8”),VS Code / Notepad++ 才能自动识别
- 不要依赖文件后缀判断编码——用 PowerShell 查:
Get-Content -Path xxx.json -Encoding Byte | Select-Object -First 3,前 3 字节是0xEF, 0xBB, 0xBF才是真 UTF-8 with BOM - 若需脚本化导出,别用 PL/SQL Developer 导出,改用
UTL_FILE+ 显式指定charset => 'AL32UTF8'(需目录对象权限)
最易忽略的是:NLS_LANG 生效 ≠ 导出编码自动同步。这两个是独立控制路径,得分别确认。










