我一直在尝试解析一个相对简单的JSON结构,但在使用APEX_JSON包时遇到了麻烦。
create table sw_json (theclob clob);
insert into sw_json values (
'{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#directoryObjects(displayName)"
,"value":[
{"@odata.type":"#microsoft.graph.group","displayName":"Group A"}
,{"@odata.type":"#microsoft.graph.group","displayName":"Group B"}
,{"@odata.type":"#microsoft.graph.group","displayName":"Group C"}
]
}');
在12 c环境中,在Jon Dixon's post的帮助下,我已经能够用SQL中的各种方法解决它。
SELECT name
FROM sw_json
nested theclob.value[*]
columns (name varchar2(100) path '$.displayName')
;
SELECT name
FROM sw_json
left outer join json_table(
theclob
, '$.value[*]' columns (name varchar2(100) path '$.displayName')
) on 1=1
;
NAME
--------
Group A
Group B
Group C
然而,为了使它在11 g中也能工作,我尝试只使用APEX_JSON。我成功地使用了感觉像是大锤的方法,但我试图用更直接的路径表达式来整理它。
declare
l_values apex_json.t_values;
l_names APEX_T_VARCHAR2;
lc_clob clob;
lc_index varchar2(200);
ln_cnt number := 1;
begin
select theclob into lc_clob
from sw_json;
apex_json.parse (
p_values => l_values,
p_source => lc_clob
);
dbms_output.put_line('Cnt:'||l_values.count);
dbms_output.put_line('First:'||l_values.First);
lc_index := l_values.First;
for i in 1..l_values.count loop
lc_index := l_values.next(lc_index);
exit when lc_index is null;
-- this seems hacky, relying on data content
if substr(l_values(lc_index).varchar2_value,1,1) ='#' then
lc_index := l_values.next(lc_index);
dbms_output.put_line(i||':'||l_values(lc_index).varchar2_value);
end if;
ln_cnt := ln_cnt +1;
end loop;
end;
/
Cnt:12
First:"@odata.context"
4:Group A
6:Group B
8:Group C
我使用jsonpath.com来验证我的表达式,但我似乎无法将其转换为APEX_JSON用法-我不禁觉得我的想法不正确。
declare
l_values apex_json.t_values;
l_names APEX_T_VARCHAR2;
lc_clob clob;
lc_index varchar2(200);
ln_cnt number := 1;
begin
select theclob into lc_clob
from sw_json;
apex_json.parse (
p_values => l_values,
p_source => lc_clob
);
dbms_output.put_line('Cnt:'||l_values.count);
dbms_output.put_line('First:'||l_values.First);
dbms_output.put_line('Test:'||apex_json.get_varchar2(p_path => '$.value.[%d][displayName]', p0 => 1));
lc_index := l_values.First;
l_names := apex_json.GET_MEMBERS (
p_values => l_values
-- tried all sorts of variations here to try match the 12c SQL
,p_path => '$.value.[%d][displayName]'
--, '$.value[*]' columns (id varchar2(100) path '$.displayName')
);
dbms_output.put_line('Cnt:'||l_names.count);
lc_index := l_names.first;
for i in 1..l_names.count loop
exit when lc_index is null;
dbms_output.put_line(ln_cnt||':'||l_names(lc_index));
lc_index := l_names.next(lc_index);
ln_cnt := ln_cnt +1;
end loop;
end;
/
不管我用什么作为路径表达式,我只是得到一些东西,它向我表明数组返回空。
Cnt:12
First:"@odata.context"
Test:
ORA-06531: Reference to uninitialized collection
尝试稍微不同的循环只返回12个空值
for i in 1..l_values.count loop
lc_str := apex_json.get_varchar2(p_path => 'value.[%d]displayName', p0 => i);
dbms_output.put_line(ln_cnt||':'||lc_str);
ln_cnt := ln_cnt +1;
end loop;
1条答案
按热度按时间bvuwiixz1#
APEX_JSON不使用“$.”符号-这是隐含的。以下作品。
apex_json.does_exist
并不是真正需要的,但它可以防止抛出异常。