Before json_mergepatch you can use basic string functions like replace.
But you need to take care with these - formatting differences may cause these to fail. It's also possible you can update multiple attributes which match your criteria.
You can do safely in pure SQL by:
- Converting the JSON object to rows-and-columns with
json_table
- Reconstructing the document with
json_object(agg) and json_array(agg), passing the new values as needed.
For example:
create table tjson (
jsoncol CLOB CONSTRAINT tjson_chk CHECK (jsoncol IS JSON)
);
insert into tjson (jsoncol) VALUES (
'{"name" : "Kunal", "LName" : "Vohra" , "salary" : "10000", "Age" : "25"}'
);
insert into tjson (jsoncol) VALUES (
'{"name" : "Rahul", "LName" : "Sharma" , "salary" : "20000", "Age" : "35"}'
);
commit;
select json_object (
'name' value j.name,
'LName' value j.LName,
'salary' value 30000, -- put new salary here
'Age' value j.Age
)
from tjson, json_table (
jsoncol, '$'
columns (
name path '$.name',
LName path '$.LName',
Age int path '$.Age'
)
) j
where j.name = 'Kunal';
JSON_OBJECT('NAME'VALUEJ.NAME,'LNAME'VALUEJ.LNAME,'SALARY'VALUE30000,--PUTNEWSALARYHERE'AGE'VALUEJ.AGE)
{"name":"Kunal","LName":"Vohra","salary":30000,"Age":25}
select t.jsoncol.name, t.jsoncol.salary
from tjson t;
NAME SALARY
Kunal 10000
Rahul 20000
update tjson t
set jsoncol = (
select json_object (
'name' value j.name,
'LName' value j.LName,
'salary' value 30000, -- put new salary here
'Age' value j.Age
)
from tjson, json_table (
jsoncol, '$'
columns (
name path '$.name',
LName path '$.LName',
Age int path '$.Age'
)
) j
where t.jsoncol.name = j.name
)
where t.jsoncol.name = 'Kunal';
select t.jsoncol.name, t.jsoncol.salary
from tjson t;
NAME SALARY
Kunal 30000
Rahul 20000
Clearly this is... cumbersome! It's impractical for complex documents.
Luckily from 12.2 you can manipulate a JSON document using PL/SQL object types:
declare
jdoc tjson.jsoncol%type;
jobj json_object_t;
begin
select t.jsoncol
into jdoc
from tjson t
where t.jsoncol.name = 'Kunal';
jobj := json_object_t.parse ( jdoc );
jobj.put ( 'salary', 40000 );
jdoc := jobj.to_clob();
update tjson t
set jsoncol = jdoc
where t.jsoncol.name = 'Kunal';
end;
/
select t.jsoncol.name, t.jsoncol.salary
from tjson t;
NAME SALARY
Kunal 40000
Rahul 20000