I have this query:
DECLARE
rc sys_refcursor;
j_keys varchar2(2000);
query_s varchar2(20000);
BEGIN
j_keys := '(
SELECT
listagg(distinct k.COLUMN_VALUE || '' varchar(256) PATH ''$.'' || k.COLUMN_VALUE, '', '') as j_cols
FROM (select json_response as json_value from SOME_TABLE where param=''some_param'') t
CROSS APPLY JSON_TABLE(
t.json_value,
''$[*]''
COLUMNS (
idx FOR ORDINALITY,
json_obj VARCHAR2(4000) FORMAT JSON PATH ''$''
)
) jt
CROSS APPLY get_keys( jt.json_obj ) k
)';
query_s := 'SELECT * FROM json_table((select json_response from SOME_TABLE where param=''some_param''), ''$[*]''
COLUMNS
' || j_keys || ')';
open rc for query_s;
dbms_sql.return_result(rc);
END;
It's a nasty query, meant to test the possibility of dynamically selecting columns for the json_table (and then parse any json-string in the selected clob - named json_response in SOME_TABLE)
Not entirely sure my syntax is set correct, but currently it complains about:
ORA-00904: invalid identifier
on line 22 (the "open rc for '...' line)
You want to run the first query rather than creating a string literal containing the text of the query and then put the output from the first query into the second query string:
DECLARE
rc sys_refcursor;
j_keys varchar2(2000);
query_s varchar2(20000);
BEGIN
SELECT listagg(
k.COLUMN_VALUE || ' varchar(256) PATH ''$.' || k.COLUMN_VALUE || '''',
','
)
INTO j_keys
FROM ( SELECT JSON_QUERY( json_value, '$[1]' RETURNING CLOB) AS json_obj
FROM table_name
)t
CROSS APPLY get_keys( t.json_obj ) k;
query_s := 'SELECT jt.*
FROM table_name t
CROSS APPLY JSON_TABLE(
t.json_value,
''$[*]''
COLUMNS
' || j_keys || ') jt';
open rc for query_s;
DECLARE
col1 VARCHAR2(50);
col2 VARCHAR2(50);
col3 VARCHAR2(50);
BEGIN
LOOP
FETCH rc INTO col1, col2, col3;
EXIT WHEN rc%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( col1 || ', ' || col2 || ', ' || col3 );
END LOOP;
END;
-- or
-- dbms_sql.return_result(rc);
END;
/
Which, given this setup:
CREATE TABLE table_name (
id NUMBER
GENERATED ALWAYS AS IDENTITY
PRIMARY KEY,
json_value CLOB
CHECK( json_value IS JSON )
);
INSERT INTO table_name ( json_value ) VALUES (
'[{"column1":"value1","column2":"value2","column3":"value3"},
{"column1":"value4","column2":"value5","column3":"value6"},
{"column3":"value9","column1":"value7","column2":"value8"}]'
);
CREATE FUNCTION get_keys(
value IN CLOB
) RETURN SYS.ODCIVARCHAR2LIST PIPELINED
IS
js JSON_OBJECT_T := JSON_OBJECT_T( value );
keys JSON_KEY_LIST;
BEGIN
keys := js.get_keys();
FOR i in 1 .. keys.COUNT LOOP
PIPE ROW ( keys(i) );
END LOOP;
END;
/
CREATE FUNCTION get_value(
value IN CLOB,
path IN VARCHAR2
) RETURN VARCHAR2
IS
js JSON_OBJECT_T := JSON_OBJECT_T( value );
BEGIN
RETURN js.get_string( path );
END;
/
Outputs:
value1, value2, value3 value4, value5, value6 value7, value8, value9
db<>fiddle here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.