如何使用Oracle的JSON函数删除JSON节点

时间:2017-11-08 23:20:51

标签: json oracle

我在Oracle数据库的VARCHAR2列中有一个如下所示的JSON字符串。

{
  "name": "Bob",
  "age": "20",
  "extras": {
    "address": "123 Main St"
  }
}

我想删除"额外内容"来自JSON字符串的节点并返回结果,如:

{
  "name": "Bob",
  "age": "20"
}

我已经知道如何使用像json_value, json_table, json_query这样的Oracle JSON函数解析JSON字符串的各个部分。不幸的是,我被困在Oracle 12.1上,因此我无法使用在{12}中添加的json_object, json_aggobject等函数。

我尝试使用类似json_query(data, '$["name"]["age"]')的路径语法(请参阅this),但似乎Oracle并不支持这种路径语法。

我可以通过从原始对象中显式提取每个已知键并使用连接重新组合来解决这个问题,例如:

select '{"name":"' || json_value(data,'$.name') 
     ||'","age":"' || json_value(data,'$.age') || '"}' result
from (
    select '{"name":"Bob","age":"20","extras":{"address":"123 Main St"}}' data
    from dual);

但是我想要这样做,以便我不会将密钥硬编码到SQL表达式中(我希望将来可能会添加其他密钥)。

如何删除" extras"没有在我的SQL语句中硬编码键列表的节点?

1 个答案:

答案 0 :(得分:1)

在oracle 12.2中,您可以执行新的调用来删除它。在下面的步骤中,我构建你的字符串,输出它,删除"额外的"并再次输出:

SET SERVEROUTPUT ON
DECLARE
  l_obj JSON_OBJECT_T;
BEGIN
  -- New empty object using constructor.
  -- With or without the NEW keyword.
  l_obj := JSON_OBJECT_T();
  DBMS_OUTPUT.put_line('l_obj.stringify = ' || l_obj.stringify);
  l_obj := NEW JSON_OBJECT_T();
  DBMS_OUTPUT.put_line('l_obj.stringify = ' || l_obj.stringify);

 -- New object based on some JSON text using constructor.
 -- With or without the NEW keyword.
  l_obj := JSON_OBJECT_T('{
  "name": "Bob",
  "age": "20",
  "extras": {
  "address": "123 Main St"
  }
}');
  DBMS_OUTPUT.put_line('l_obj.stringify = ' || l_obj.stringify);

  -- remove "extras"
  l_obj.remove('extras');
  DBMS_OUTPUT.put_line('l_obj.stringify = ' || l_obj.stringify);
END;
/