Oracle 19c的PL/SQL层未新增JSON解析能力,仅能通过SQL语句间接调用JSON_TABLE、JSON_SERIALIZE等函数;因JSON_TABLE是表函数,必须在SELECT中使用,不可直接赋值,且所有JSON功能均依赖SQL引擎解析,运行时易出现延迟报错。

Oracle 19c 的 PL/SQL 层本身没有新增 JSON 解析能力,真正的改进在 SQL 层和类型系统——PL/SQL 只是借力使用,不能直接调用 JSON_TABLE 或 JSON_SERIALIZE 等新函数。
为什么 PL/SQL 过程里不能直接用 JSON_TABLE?
JSON_TABLE 是一个表函数(table function),必须嵌套在 SELECT 语句中使用,不能出现在纯 PL/SQL 块的赋值或条件判断里。你在 PL/SQL 中写 SELECT * FROM JSON_TABLE(...) 是合法的,但写 my_var := JSON_TABLE(...) 会报 ORA-00904 “invalid identifier”。
常见错误现象:
- 误以为
JSON_TABLE返回一个对象或集合,试图直接赋值给JSON_OBJECT_T或JSON_ARRAY_T - 在
FOR rec IN (JSON_TABLE(...)) LOOP中漏写SELECT,导致编译失败
PL/SQL 能用的 19c 新 JSON 工具只有这些
真正能在 PL/SQL 中直接调用的 19c 新特性非常有限,主要是:
-
JSON_SERIALIZE:可在SELECT ... INTO或EXECUTE IMMEDIATE中调用,把 JSON 值转成可读字符串,比如SELECT JSON_SERIALIZE(json_col) INTO l_str FROM t WHERE id = 1 -
JSON_MERGEPATCH:只能用于 DML 或子查询,PL/SQL 中需通过EXECUTE IMMEDIATE执行含该函数的 UPDATE 语句 -
JSON_OBJECT/JSON_ARRAY构造函数:支持关键字ABSENT ON NULL和STRICT模式,在 PL/SQL 动态拼 SQL 时更可控
注意:JSON_OBJECT_T 和 JSON_ARRAY_T 类型本身在 12.2 就已存在,19c 只是增强了其方法(如 to_clob() 支持缩进参数),但不改变调用方式。
LISTAGG(DISTINCT ...) 在 JSON 场景下的真实价值
这不是 JSON 函数,但对 JSON 处理很实用:当你要把一组标签、权限、角色拼成 JSON 数组字段时,常需去重。以前得靠 GROUP BY + ROW_NUMBER() 或临时表,现在可以直接:
SELECT JSON_ARRAY( LISTAGG(DISTINCT tag, ',') WITHIN GROUP (ORDER BY tag) FORMAT JSON ) AS tags_json FROM user_permissions;
关键点:
-
LISTAGG(DISTINCT ...)必须配合GROUP BY或聚合上下文,不能在普通 SELECT 中裸用 -
FORMAT JSON是 19c 新增语法,确保输出被识别为 JSON 类型而非普通字符串 - 若目标列是
JSON类型(21c+),这比手拼'["' || ... || '"]'更安全,避免引号逃逸问题
最容易被忽略的是:所有这些“PL/SQL 可用”的 JSON 功能,底层仍依赖 SQL 引擎解析。一旦你把 JSON_SERIALIZE 用在绑定变量未正确传入的动态 SQL 里,或者路径表达式里用了 12c 不支持的 $[*] 语法,错误不会在 PL/SQL 编译时报出,而是在运行时抛 ORA-40442(JSON path error)——这种延迟报错很难调试。


















