С учетом этой таблицы:
create table silo_sensor (
name varchar2(255),
devices_id varchar2(255)
);
Должно работать следующее:
declare
tv apex_json.t_values;
v_clob clob;
scount number;
ccount number;
q_temp varchar2(255);
v_id varchar2(255);
begin
v_clob := q'-
{
"GroupSensor": [
{
"silos": 1,
"GroupBob": [
"SENSOR0001",
"SENSOR0002",
"SENSOR0003",
"SENSOR0004",
"SENSOR0005",
"SENSOR0006",
"SENSOR0007",
"SENSOR0008",
"SENSOR0009",
"SENSOR0010"
],
"SerialNumber": "1701"
},
{
"silos": 1,
"GroupBob": [
"SENSOR0011",
"SENSOR0012",
"SENSOR0013",
"SENSOR0014",
"SENSOR0015",
"SENSOR0016",
"SENSOR0017",
"SENSOR0018",
"SENSOR0019"
],
"SerialNumber": "1702"
},
{
"silos": 1,
"GroupBob": [
"SENSOR0020",
"SENSOR0021",
"SENSOR0022",
"SENSOR0023",
"SENSOR0024",
"SENSOR0025",
"SENSOR0026",
"SENSOR0027",
"SENSOR0028"
],
"SerialNumber": "1703"
}
]
}
-';
apex_json.parse(tv, v_clob);
sCount := APEX_JSON.get_count(p_path => 'GroupSensor' , p_values => tv);
for i in 1 .. sCount loop
v_id := apex_json.get_varchar2(p_path => 'GroupSensor[%d].SerialNumber', p_values => tv, p0 => i);
cCount := APEX_JSON.get_count(p_path => 'GroupSensor[%d].GroupBob' , p_values => tv, p0 => i);
for q in 1 .. cCount loop
q_temp := apex_json.get_varchar2(p_path => 'GroupSensor[%d].GroupBob[%d]', p_values => tv, p0 => i, p1 => q);
insert into silo_sensor(name, devices_id)
values (q_temp, v_id);
end loop;
end loop;
commit;
end;
Несколько замечаний:
Вы не нужны чеки IF sCount > 0 THEN
или IF cCount > 0 THEN
. Просто go в l oop, если счет равен 0, вы не будете go в него. Единственная причина, по которой вам может понадобиться проверка if
, заключается в том, что, возможно, свойство не существует. В этом случае ваш чек должен быть if sCount is not null
, потому что get_varchar2
вернет ноль, если свойство не существует.
Не фиксируйте внутри al oop. Если во время цикла вы получите ошибку, вы совершите часть транзакции, и ее будет сложнее исправить. Либо зафиксировать в конце, либо не делать вообще (пусть вызывающий коммитит, когда захочет).
Поскольку вы работаете на 18 c, вы можете использовать встроенный PL / SQL типов для JSON. Они должны работать лучше, чем APEX_ JSON.
declare
top_obj json_object_t;
gs_arr json_array_t;
gs_obj json_object_t;
gb_arr json_array_t;
v_clob clob;
q_temp varchar2(255);
v_id varchar2(255);
begin
v_clob := q'-
{
"GroupSensor": [
{
"silos": 1,
"GroupBob": [
"SENSOR0001",
"SENSOR0002",
"SENSOR0003",
"SENSOR0004",
"SENSOR0005",
"SENSOR0006",
"SENSOR0007",
"SENSOR0008",
"SENSOR0009",
"SENSOR0010"
],
"SerialNumber": "1701"
},
{
"silos": 1,
"GroupBob": [
"SENSOR0011",
"SENSOR0012",
"SENSOR0013",
"SENSOR0014",
"SENSOR0015",
"SENSOR0016",
"SENSOR0017",
"SENSOR0018",
"SENSOR0019"
],
"SerialNumber": "1702"
},
{
"silos": 1,
"GroupBob": [
"SENSOR0020",
"SENSOR0021",
"SENSOR0022",
"SENSOR0023",
"SENSOR0024",
"SENSOR0025",
"SENSOR0026",
"SENSOR0027",
"SENSOR0028"
],
"SerialNumber": "1703"
}
]
}
-';
top_obj := json_object_t.parse(v_clob);
gs_arr := top_obj.get_array('GroupSensor');
for i in 0 .. gs_arr.get_size - 1 loop
gs_obj := json_object_t(gs_arr.get(i));
v_id := gs_obj.get_string('SerialNumber');
gb_arr := gs_obj.get_array('GroupBob');
for q in 0 .. gb_arr.get_size - 1 loop
q_temp := gb_arr.get_string(i);
insert into silo_sensor(name, devices_id)
values (q_temp, v_id);
end loop;
end loop;
commit;
end;