我一直在尝试修改Oracle DB中的CLOB字段(出于性能原因),该字段存储了一个JSON数组。
考虑这个微不足道的例子
+----+-----+------------------------------------------------------------------------------------------------------------------------------------+
| ID | COL | Json |
+----+-----+------------------------------------------------------------------------------------------------------------------------------------+
| 10 | 12 | [{"id":4, "name":"Jhon", age:40, opinion:null},{"id":3, name:"Jane", age:7},{"id":7, "name":"Peter", age:12, opinion:"somevalue"}] |
| 20 | 27 | [{"id":10, "name":"Julian", age:40, opinion:"somevalue"}] |
| 30 | 40 | [{"id":30, "name":"Paul", age:20, opinion:"opinion"},{"id":3, name:"Jane", age:7}] |
+----+-----+------------------------------------------------------------------------------------------------------------------------------------+
我的目标是获得一个表,其中必须根据条件过滤Json
列(它是一个CLOB,因为它可能非常大)。在这个例子中,假设条件是删除所有带有opinion = "somevalue"
的json。结果将是:
+----+-----+------------------------------------------------------------------------------------+
| ID | COL | Json |
+----+-----+------------------------------------------------------------------------------------+
| 10 | 12 | [{"id":4, "name":"Jhon", age:40, opinion:null},{"id":3, name:"Jane", age:7}] |
| 20 | 27 | [] |
| 30 | 40 | [{"id":30, "name":"Paul", age:20, opinion:"opinion"},{"id":3, name:"Jane", age:7}] |
+----+-----+------------------------------------------------------------------------------------+
我的尝试:
我尝试使用JSON_ARRAYAGG函数来解决这个问题,但它不起作用。我的意思是,它的工作原理假设我不限制查询到一个特定的id。这是查询:
UPDATE table t SET t.JSON = (SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'id' VALUE jt.id,
'opinion' VALUE jt.opinion,
'age' VALUE jt.age,
'name' VALUE jt.name
) RETURNING CLOB )
FROM JSON_TABLE(
t.JSON, '$[*]'
COLUMNS (
age NUMBER PATH '$.age',
opinion VARCHAR2(4000) PATH '$.opinion',
id number PATH '$.id',
name VARCHAR2(4000) PATH '$.name'
)
) jt WHERE jt.opinion <> 'somevalue');
如果我这样修改它:
UPDATE table t SET t.JSON = (SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'id' VALUE jt.id,
'opinion' VALUE jt.opinion,
'age' VALUE jt.age,
'name' VALUE jt.name
) RETURNING CLOB )
FROM JSON_TABLE(
t.JSON, '$[*]'
COLUMNS (
age NUMBER PATH '$.age',
opinion VARCHAR2(4000) PATH '$.opinion',
id number PATH '$.id',
name VARCHAR2(4000) PATH '$.name'
)
) jt WHERE jt.opinion <> 'somevalue') WHERE t.id = 10;
我在唯一修改的行上收到了错误的预期值(就像单个修改行中所有行的所有JSON一样)。我想知道发生了什么,方法是否正确。
PS:请考虑JSON
不是col的真实的名称,所以它不会与任何东西冲突。
1条答案
按热度按时间enxuqcxy1#
如果你在19号。10或更高,使用
json_transform
更容易。搜索表达式
'$[*]?(@.opinion == "somevalue")'
标识opinion为“somevalue”的数组元素。使用remove
子句将这些条目从文档中删除: