Oracle 中 JSON 查询的动态列列表

问题描述 投票:0回答:1

我正在寻找一种创建/传递动态列列表以用于生成 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"]]}

小提琴

json oracle dynamic key-value json-arrayagg
1个回答
0
投票

您可以创建一个辅助函数:

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]]}

Oracle 21 小提琴

© www.soinside.com 2019 - 2024. All rights reserved.