json_table必须作为from子句中的表源使用,不能当标量函数调用;正确用法是cross join或逗号连接,并配合nested path处理嵌套数组、on empty/on error显式控制空值、先过滤后解析提升性能。

JSON_TABLE必须作为FROM子句中的数据源,不能当普通函数用
很多人一上来就写 SELECT id, JSON_TABLE(json_col, '$' COLUMNS (name VARCHAR2(50) PATH '$.name')) FROM t,直接报 ORA-00923: FROM keyword not found。这不是语法错,是根本性误解:JSON_TABLE不是TO_CHAR那种标量函数,它生成的是一个虚拟表,只能出现在FROM或LATERAL位置。
正确姿势是把它当“表”来连接:
SELECT jt.name FROM t, JSON_TABLE(t.json_col, '$' COLUMNS (name VARCHAR2(50) PATH '$.name')) jt- 或者更清晰的显式
CROSS JOIN:SELECT jt.name FROM t CROSS JOIN JSON_TABLE(t.json_col, '$' COLUMNS (name VARCHAR2(50) PATH '$.name')) jt
路径里的$必须带单引号包裹,且不能拼接——'{"a":' || 1 || '}'这种动态拼JSON字符串会触发ORA-40441。
嵌套数组展开别硬套两层JSON_TABLE,优先用NESTED PATH
接口报文常见结构如 {"orders":[{"id":1,"items":[{"sku":"A"},{"sku":"B"}]}]}。想让每行返回order.id和一个item.sku,有人会先JSON_TABLE取orders得jt1,再对jt1.items做第二层JSON_TABLE——这容易出笛卡尔积,也难维护。
Oracle 12.2+ 正确写法是单层+NESTED PATH:
JSON_TABLE(json_col, '$.orders[*]' COLUMNS (
order_id NUMBER PATH '$.id',
NESTED PATH '$.items[*]' COLUMNS (
sku VARCHAR2(20) PATH '$.sku'
)
)) jt
关键点:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
NESTED PATH自动处理父子关联,避免手动CROSS JOIN带来的重复和空值丢失 - 数组路径必须写
[*],写[0]只取第一个,写.items.sku会静默返回NULL - 字段名含空格或连字符,要用双引号:
$.["order-id"]
路径写错不报错,只返回NULL——必须加ON EMPTY/ON ERROR显式控制
JSON_TABLE对路径极其敏感,但错误时从不抛异常,只默默返回NULL。比如键名大小写不对("Name" vs "name")、漏写$、数组没加[*],结果都是空——你很难区分是数据真为空,还是路径写错了。
防坑做法:
- 所有
PATH后紧跟ON EMPTY NULL ON ERROR NULL,避免意外中断 - 对可能缺失的字段,用
DEFAULT 'N/A' ON EMPTY明确占位 - 调试时先用
JSON_QUERY(json_col, '$.orders') WITH CONDITIONAL确认原始结构是否存在
示例:id NUMBER PATH '$.id' DEFAULT -1 ON EMPTY ON ERROR,比裸写PATH '$.id'可靠得多。
大批量解析性能差?先过滤再解析,别在JOIN里反复调用
JSON_TABLE是运行时逐行解析,无法走索引。如果对全表每行都执行,10万条记录可能拖慢查询数秒甚至分钟。
提速关键不是优化JSON_TABLE本身,而是减少它的调用次数:
- 先用
json_exists(json_col, '$?(@.status == "success")')过滤掉无效报文,再进JSON_TABLE - 避免在
WHERE子句里写JSON_VALUE(json_col, '$.id') = 123——改用虚拟列+索引:ALTER TABLE t ADD (id_val NUMBER GENERATED ALWAYS AS (json_value(json_col, '$.id'))),然后CREATE INDEX idx_t_idval ON t(id_val) - 如果解析逻辑固定,封装成物化视图,避免每次查询都重解析
真正卡住的往往不是JSON解析本身,而是没意识到它被放在了低效执行计划的内层循环里。










