Предполагая, что ваша таблица похожа на эту:
create table table_name
(
id number(12) primary key,
route_sequence number(12),
updated_by varchar2(30),
updated_on timestamp(9)
)
и что объект json похож на этот:
{
"activities":
[
{"task_id": 1, "sequence" : 10},
{"task_id": 2, "sequence" : 20},
{"task_id": 3, "sequence" : 30},
{"task_id": 4, "sequence" : 40},
{"task_id": 5, "sequence" : 50},
]
}
Вы можете напрямую запрашивать данные json в SQL, используяSQL-оператор "JSON_TABLE" (новичок в oracle 12 - см. https://docs.oracle.com/database/121/SQLRF/functions092.htm#SQLRF56973)..., а затем вы можете воспользоваться этим, используя такой запрос в операторе "слияния":
этот единственный оператор SQL делаетчто вам нужно:
merge into table_name t
using
(
select *
from JSON_TABLE(
'{
"activities":
[
{"task_id": 1, "sequence" : 10},
{"task_id": 2, "sequence" : 20},
{"task_id": 3, "sequence" : 30},
{"task_id": 4, "sequence" : 40},
{"task_id": 5, "sequence" : 50},
]
}',
'$."activities"[*]'
COLUMNS(
V_TASK_ID NUMBER PATH '$.task_id',
V_SEQ NUMBER PATH '$.sequence'
)
)
) json_data
on (json_data.v_task_id = t.id)
when matched then
update set
ROUTE_SEQUENCE = V_SEQ,
UPDATED_BY = 'SYSTEM',
UPDATED_ON = SYSTIMESTAMP
Редактировать: теперь, когда вы опубликовали свой фактический пример json:
, чтобы мой пример работал с вашими данными, вам просто нужно заменить
'$."activities"[*]'
строка с этим:
'$."plan"[0]."activities"[*]'
вещь может стать более сложной, если элемент массива «план» содержит более одного элемента, но это все еще можно сделать.
Редактировать 2: как обрабатывать вложенные объекты (то есть: что делать, когда «план» содержит несколько объектов
Предположим, что строка json, которая должна быть обработана, является этой
'{
"plan":
[
{
"vehicle_id": "vehicle_1",
"activities":
[
{
"sequence": 1,
"task_id": "465427"
},
{
"sequence": 2,
"task_id": "443951"
}
]
}
,
{
"vehicle_id": "vehicle_2",
"activities":
[
{
"sequence": 3,
"task_id": "165760"
},
{
"sequence": 4,
"task_id": "459187"
}
]
}
]
}'
(Я не буду повторять это в моих примерах: я просто напишу в коде
Если вы не заинтересованы в чтении поля vehicle_id и хотите получить подробное представление обо всех подробностях действий (независимо от того, какой объект «плана» содержит их, вы можете просто изменить строку селектора корневого объекта из этого * 1034)*
'$."plan"[0]."activities"[*]'
на это:
'$."plan"[*]."activities"[*]'
так, этот запрос:
select *
from JSON_TABLE
(
<json_string_here>,
'$."plan"[*]."activities"[*]'
COLUMNS(
V_TASK_ID NUMBER PATH '$.task_id',
V_SEQ NUMBER PATH '$.sequence'
)
)
будет проходить через все объекты "деятельности" всех объектов плана, но он будет возвращатьВы только столбцы "task_id" и "sequence".
Если вы хотите вместо этого также повторить соответствующий столбец идентификатора транспортного средства во всех строках, вы должны перейти на уровень с корневым селектором, используя этоВыражение
'$."plan"[*]'
и внутри предложения «columnns» вы можете использовать синтаксис «вложенного пути», чтобы указать, что вы хотите расширить встроенные столбцы подобъекта:
select *
from JSON_TABLE
(
<json_string_here>,
'$."plan"[*]'
COLUMNS
(
VEHICLE varchar2(20) PATH '$."vehicle_id"',
NESTED PATH '$."activities"[*]'
COLUMNS
(
V_TASK_ID NUMBER PATH '$.task_id',
V_SEQ NUMBER PATH '$.sequence'
)
)
)