Oracle解析键数超32767的JSON报ORA-40684错误如何解决
问题描述
解析单对象键总数超过32767的JSON数据时,需提取所有键值对存入临时表,但调用PL/SQL原生JSON接口时受长度限制报错。
待处理JSON为平铺键值对结构,示例如下:
{"1335":"345435sd","8989SD":"jddk8","dDDSF":"87868658"......}
原有PL/SQL处理代码如下:
declare j JSON_OBJECT_T; i NUMBER; k JSON_KEY_LIST; arr JSON_ARRAY_T; v_key varchar2(2000); v_value varchar2(2000); CURSOR c_json IS select treat(col_clob as json) myJsonCol from t_clob; -- 源数据存储在CLOB字段中 begin FOR rec IN c_json LOOP j := JSON_OBJECT_T.parse(rec.myJsonCol); k := j.get_keys; FOR i in 1..k.COUNT LOOP dbms_output.put_line(k(i) || ' ' || j.get_String(k(i))); v_key :=k(i); v_value :=j.get_String(k(i)); -- insert into temp(c1,c2) values(v_key,v_value); END LOOP; END LOOP; END; /
运行代码抛出错误:
ORA-40684: maximum number of key names exceeded
根据官方说明,PL/SQL方法JSON_OBJECT_T.get_keys()针对单个JSON对象最多仅返回32767个字段名,对象键数超过该阈值时会直接抛出异常,无法完成全量键值提取。
可行解决方案
- 方案1:使用
JSON_TABLE原生SQL函数解析,绕过PL/SQL对象接口限制
该方式直接在SQL层解析CLOB格式JSON,不受PL/SQLget_keys()方法的返回条数限制,代码量最小、解析性能最优,适配12.2及以上版本Oracle数据库,示例代码:
其中路径表达式-- 直接解析全量键值对插入临时表 INSERT INTO temp(c1, c2) SELECT jt.key_name, jt.key_value FROM t_clob t, JSON_TABLE( t.col_clob, '$.*' COLUMNS ( key_name VARCHAR2(2000) PATH '$?parent_key()', key_value VARCHAR2(2000) PATH '$' ) ) jt;$?parent_key()可直接获取当前遍历节点对应的键名,无需提前获取全量键列表,从根源上避开32767的数量限制。 - 方案2:拆分超大JSON为多个子对象分批解析
若使用的数据库版本不支持$?parent_key()路径语法,可先按JSON格式规则将原超大对象拆分为多个键数小于32767的子JSON对象,再循环调用原有get_keys()逻辑分批提取键值对入库。拆分时需严格处理JSON转义字符,避免截断字符串值、转义符导致JSON格式非法。 - 方案3:升级数据库版本
Oracle 18c及以上版本放宽了JSON接口的数量限制,JSON_KEY_LIST的最大长度上限大幅提升,可直接支持更大规模的单对象键遍历,无需改造原有PL/SQL代码即可正常运行。
内容的提问来源于stack exchange,提问作者Stay Curious
相关产品推荐
相关产品推荐

