如何用JSON_ARRAYAGG合并多行结果为嵌套JSON及解决ORA-40478报错
问题描述
尝试使用JSON_ARRAYAGG将多行查询结果转换为嵌套JSON列表时遇到以下问题:
- 需要将重复的
col3值合并为数组,生成结构统一的单个JSON对象(如期望输出所示) - 添加
JSON_ARRAYAGG后触发报错:ORA-40478: output value too large (maximum: 4000) - 已尝试
RETURNING CLOB、TO_CLOB(JSON_OBJECT())、DBMS_LOB包等方法,但未解决问题
原始非JSON查询结果:
| col1 | col2 | col3 | col5 | col6 | col7 |
|---|---|---|---|---|---|
| 12345 | 1 | 654321 | test | 2345 | 14 |
| 12345 | 1 | 765432 | test | 2345 | 14 |
当前JSON查询语句(生成两个独立JSON对象):
SELECT DISTINCT JSON_OBJECT( 'col1' VALUE mytable.col1, 'col2' VALUE '1', 'col3' VALUE TO_CHAR(table2.col3), 'col4' VALUE JSON_OBJECT( 'col5' VALUE 'test', 'col6' VALUE TO_CHAR(mytable.col1) ABSENT ON NULL ), 'col7' VALUE ( SELECT FLOOR(MAX(days)/30) FROM schema1.table1 WHERE table1.test = mytable.test ) ABSENT ON NULL ) AS output FROM mytable join table2 on mytable.col1=table2.col1
当前输出(两个独立JSON对象):
{ "col1": 12345, "col2": "1", "col3": "654321", "col4": { "col5": "test", "col6": "2345" }, "col7": 14 } { "col1": 12345, "col2": "1", "col3": "765432", "col4": { "col5": "test", "col6": "2345" }, "col7": 14 }
期望输出(单个JSON对象,col3为数组):
{ "col1": 12345, "col2": "1", "col3": [ "654321", "765432"], "col4": { "col5": "test", "col6": "2345" }, "col7": 14 }
解决方案
1. 重写查询实现嵌套数组结构
通过GROUP BY对重复的主字段分组,使用JSON_ARRAYAGG聚合col3为数组,同时指定返回CLOB类型规避长度限制:
SELECT JSON_OBJECT( 'col1' VALUE m.col1, 'col2' VALUE '1', 'col3' VALUE JSON_ARRAYAGG(TO_CHAR(t2.col3) ORDER BY t2.col3) RETURNING CLOB, 'col4' VALUE JSON_OBJECT( 'col5' VALUE 'test', 'col6' VALUE TO_CHAR(m.col1) ABSENT ON NULL ), 'col7' VALUE ( SELECT FLOOR(MAX(days)/30) FROM schema1.table1 t1 WHERE t1.test = m.test ) ABSENT ON NULL RETURNING CLOB) AS output FROM mytable m JOIN table2 t2 ON m.col1 = t2.col1 GROUP BY m.col1, m.test
2. 解决ORA-40478报错的关键
之前尝试失败是因为未在JSON_ARRAYAGG和外层JSON_OBJECT同时指定RETURNING CLOB:
JSON_ARRAYAGG(...) RETURNING CLOB:让聚合后的数组直接以CLOB返回,突破VARCHAR2的4000字符上限- 外层
JSON_OBJECT(...) RETURNING CLOB:确保最终整个JSON对象以CLOB形式输出,容纳更大内容
3. 注意事项
GROUP BY必须包含所有非聚合字段(m.col1、m.test),保证分组内col4、col7的值唯一ORDER BY t2.col3可选,用于指定数组内元素的排序顺序ABSENT ON NULL保留原有逻辑,自动忽略值为NULL的键
内容的提问来源于stack exchange,提问作者Anupa Reddy
相关产品推荐
相关产品推荐

