如何使用新属性值更新 JSON 列?
How to update JSON column with new attribute value?
我有一种情况需要在 table 中动态更新 json 列。请参阅下面的结构
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"}');
现在我需要在some_condition
的基础上,把salary
改成一个动态值来完成table
我可以使用 JSON_VALUE(jsoncol, '$.Age')
读取数据
update tjson
set jsoncol = '"salary":$JustChangeSalary'
where some_condition;
工资是动态的,不是固定的。我愿意换薪水
我尝试了 json_mergepatch
,但只能从 Oracle version 19
获得。我们正在使用 Oracle version 12.2
假设要更新Kunal的工资为15000,那么在WHERE条件中使用JSON_EXISTS()
函数只带他的记录,后面使用传统的REPLACE()
函数SET 子句,文字摘录包含与 salary
相关的键值组合,如
UPDATE tjson
SET jsoncol = REPLACE( jsoncol, '"salary" : "10000"', '"salary" : "15000"' )
WHERE JSON_EXISTS(jsoncol, '$.name?(@ == "Kunal")');
在 json_mergepatch
之前,您可以使用基本的字符串函数,例如 replace
。
但您需要注意这些 - 格式差异可能会导致这些失败。您也可以更新符合您条件的多个属性。
您可以通过以下方式在纯 SQL 中安全地进行操作:
- 使用
json_table
将 JSON 对象转换为行和列
- 正在使用
json_object(agg)
和 json_array(agg)
重建文档,根据需要传递新值。
例如:
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
显然这很……麻烦!对于复杂的文档不切实际。
幸运的是,从 12.2 开始,您可以使用 PL/SQL 对象类型操作 JSON 文档:
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
我有一种情况需要在 table 中动态更新 json 列。请参阅下面的结构
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"}');
现在我需要在some_condition
salary
改成一个动态值来完成table
我可以使用 JSON_VALUE(jsoncol, '$.Age')
update tjson
set jsoncol = '"salary":$JustChangeSalary'
where some_condition;
工资是动态的,不是固定的。我愿意换薪水
我尝试了 json_mergepatch
,但只能从 Oracle version 19
获得。我们正在使用 Oracle version 12.2
假设要更新Kunal的工资为15000,那么在WHERE条件中使用JSON_EXISTS()
函数只带他的记录,后面使用传统的REPLACE()
函数SET 子句,文字摘录包含与 salary
相关的键值组合,如
UPDATE tjson
SET jsoncol = REPLACE( jsoncol, '"salary" : "10000"', '"salary" : "15000"' )
WHERE JSON_EXISTS(jsoncol, '$.name?(@ == "Kunal")');
在 json_mergepatch
之前,您可以使用基本的字符串函数,例如 replace
。
但您需要注意这些 - 格式差异可能会导致这些失败。您也可以更新符合您条件的多个属性。
您可以通过以下方式在纯 SQL 中安全地进行操作:
- 使用
json_table
将 JSON 对象转换为行和列
- 正在使用
json_object(agg)
和json_array(agg)
重建文档,根据需要传递新值。
例如:
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
显然这很……麻烦!对于复杂的文档不切实际。
幸运的是,从 12.2 开始,您可以使用 PL/SQL 对象类型操作 JSON 文档:
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