json_table必须出现在from子句中,不能作为函数在select或where中直接调用;pl/sql中须通过select into调用,嵌套数组推荐用nested path(12.2+)或双层json_table(12.1),路径为相对路径且大小写敏感,空值默认返回null而非报错。

JSON_TABLE 必须出现在 FROM 子句,不能当函数用
PL/SQL 里写 JSON_TABLE(json_str, '$' COLUMNS (x VARCHAR2(10) PATH '$.x')) 直接报错 ORA-00923 —— 它不是函数,是表构造器。所有使用都得走 SQL 引擎,且只能作为数据源出现在 FROM 或隐式横向连接中。
常见错误写法:SELECT id, JSON_TABLE(json_col, '$' COLUMNS (name PATH '$.name')) FROM t
正确做法必须包裹成派生表:
SELECT jt.name FROM t, JSON_TABLE(t.json_col, '$' COLUMNS (name VARCHAR2(50) PATH '$.name')) jt- 路径参数支持列名(
t.json_col)、绑定变量(:json_str)、字面量('{"a":1}'),但不能是拼接字符串(如'{"a":' || 1 || '}') - 若在 PL/SQL 块中使用,必须配合
SELECT ... INTO,例如:SELECT jt.name INTO l_name FROM DUAL, JSON_TABLE(:json_str, '$' COLUMNS (name VARCHAR2(50) PATH '$.name')) jt
嵌套数组必须用 NESTED PATH,别硬写双重 JSON_TABLE
面对 {"orders":[{"id":1,"items":[{"sku":"A"},{"sku":"B"}]}]} 这类结构,想展开成 2 行(order.id + item.sku),只靠一层 JSON_TABLE 无法实现;手动写两层关联容易引入笛卡尔积、类型不匹配或空数组丢行。
Oracle 12.2+ 推荐用 NESTED PATH:
JSON_TABLE(json_str, '$.orders[*]' COLUMNS (order_id NUMBER PATH '$.id', NESTED PATH '$.items[*]' COLUMNS (sku VARCHAR2(20) PATH '$.sku')))- 路径是相对的:
NESTED PATH '$.items[*]'的$指向上一级(即每个 order 对象),不是根节点 - 加
NULL ON EMPTY可让缺失items的 order 仍保留一行(sku为 NULL),否则整行被过滤 - 12.1 版本不支持
NESTED PATH,只能用双层调用,但需注意jt1.items是 JSON 片段,必须显式声明类型或加FORMAT JSON才能传给第二层
PL/SQL 中不能直接赋值调用 JSON_VALUE 或 JSON_TABLE
l_val := JSON_VALUE(l_json, '$.x') 会报 PLS-00222:函数未定义。PL/SQL 没有原生 JSON 解析器,所有 JSON 函数都属于 SQL 引擎范畴。
必须走 SELECT INTO:
- 单字段:
SELECT JSON_VALUE(json_str, '$.name') INTO l_name FROM DUAL - 多字段建议一次查出:
SELECT JSON_VALUE(json_str,'$.name'), JSON_VALUE(json_str,'$.age') INTO l_name, l_age FROM DUAL - 解析数组或对象时,
JSON_VALUE返回字符串,若要保留 JSON 结构(比如子对象),必须用JSON_QUERY(... RETURNING CLOB)并确保目标变量是CLOB - 类型精度易错:
NUMBER PATH '$.price'若实际值是99.954,定义为NUMBER(3,1)会静默截断为99.9,不报错但数据失真
空值、越界、大小写敏感这些细节不报错但会静默失效
Oracle JSON 函数对错误很“宽容”:路径不存在、数组索引越界、大小写不匹配,通常返回 NULL 而非报错——这导致逻辑看似跑通,结果却为空或错乱。
- JSON 键名严格区分大小写:
'$.Name'和'$.name'是不同路径 - 数组访问越界(如
'$.tags[99]')返回 NULL,不会中断执行 - 没加
ERROR ON ERROR时,语法错误路径也返回 NULL,很难定位问题源头 -
IS JSON约束和虚拟列索引能加速查询,但仅对已校验过的合法 JSON 生效;无效 JSON 字符串存入后,JSON_TABLE会跳过整行,不提示
真正麻烦的不是语法写错,而是它不告诉你错了——你得自己验证每层路径是否存在、类型是否匹配、空值是否被预期丢弃。











