我正在寻找一种创建/传递动态列列表以用于生成 JSON 文档的方法。
创建以下内容(在 Oracle 19c 上):
CREATE TABLE tbl1 (val1 varchar2(10), val2 varchar2(10), val3 varchar2(10));
INSERT INTO tbl1 VALUES ('1','2','3');
INSERT INTO tbl1 VALUES ('a','b','c');
INSERT INTO tbl1 VALUES ('1','b','3');
此查询为我提供了我想要的输出,但对于键和值部分中的列名称(或 val1、val2、val3)来说是静态的。
with qry as (
select *
from tbl1
)
select json_object(
'keys' : ['VAL1', 'VAL2', 'VAL3'],
'values' : json_arrayagg(json_array(val1, val2, val3 null on null))) as js
from qry
JS |
---|
{“键”:[“VAL1”,“VAL2”,“VAL3”],“值”:[[“1”,“2”,“3”],[“a”,“b”,“c "],["1","b","3"]]} |
我正在寻找一种用动态列表替换键和值部分的方法。这并不完全正确(仍然有静态值调用,并且在键的每一端都被额外的“包围”,但已经是我能够实现的最接近的了。寻求帮助以使其完全动态化。理想情况下是能够更改 with 子句中的表并构建其他表。
with qry as (
select tbl1.*,
(select
listagg ('''''' || column_name || '''''', ',') within group (order by column_name)
from all_tab_cols
where table_name = 'TBL1') as cols
from tbl1
)
select json_object(
'keys' : [json_query(json_arrayagg(qry.cols), '$[0]') FORMAT JSON],
'values' : json_arrayagg(json_array(val1, val2, val3 null on null))) as js
from qry
JS |
---|
{"键":["''VAL1'',''VAL2'',''VAL3''"],"值":[["1","2","3"],["1 ","b","3"],["a","b","c"]]} |
您可以创建一个辅助函数:
CREATE FUNCTION object_to_array(
value IN VARCHAR2
) RETURN VARCHAR2
IS
js JSON_OBJECT_T := JSON_OBJECT_T( value );
arr JSON_ARRAY_T := JSON_ARRAY_T();
keys JSON_KEY_LIST := js.get_keys();
BEGIN
FOR i in 1 .. keys.COUNT LOOP
arr.append(js.get_string(keys(i)));
END LOOP;
RETURN arr.to_string();
END;
/
然后你可以使用:
SELECT json_object(
KEY 'keys' VALUE MIN(p.keys) FORMAT JSON,
KEY 'values' VALUE JSON_ARRAYAGG(object_to_array(t.json) FORMAT JSON)
) as js
FROM (SELECT JSON_OBJECT(*) AS json FROM tbl1) t
CROSS JOIN LATERAL(
SELECT JSON_DATAGUIDE(t.json) AS data FROM DUAL
) d
CROSS JOIN LATERAL(
SELECT JSON_ARRAYAGG(SUBSTR(path, 3)) AS keys
FROM JSON_TABLE(
d.data,
'$[*]'
COLUMNS(
path VARCHAR2(20) PATH '$."o:path"'
)
)
WHERE path != '$'
) p
对于样本数据:
CREATE TABLE tbl1 (val1 varchar2(10), val2 varchar2(10), val3 varchar2(10));
INSERT INTO tbl1 VALUES ('1','2','3');
INSERT INTO tbl1 VALUES ('a','b','c');
INSERT INTO tbl1 VALUES ('1','b','3');
INSERT INTO tbl1 VALUES ('2','d',NULL);
输出:
JS |
---|
{“键”:[“VAL1”,“VAL2”,“VAL3”],“值”:[[“1”,“2”,“3”],[“a”,“b”,“c "],["1","b","3"],["2","d",null]]} |