在 Oracle 中使用 SQL 操作 JSON 数据

Posted

技术标签:

【中文标题】在 Oracle 中使用 SQL 操作 JSON 数据【英文标题】:Manipulating JSON data with SQL in Oracle 【发布时间】:2018-02-03 19:04:33 【问题描述】:

我的 Oracle (v12.2) 表中有一个 CLOB 字段,如下所示:

CREATE TABLE dmo_person (
    per_id RAW(16) CONSTRAINT NN_per_id NOT NULL,
    per_name VARCHAR2(128),
    per_tags CLOB CONSTRAINT dmo_pers_json_0 CHECK (per_tags IS JSON),
    CONSTRAINT sko_person_pk_0 PRIMARY KEY (per_id)
);

JSON 数据的结构如下:

insert into dmo_person
 ( per_id, per_name, per_tags  )
values
 (
 sys_guid(),
 'John Doe',
 ' "perm_admin" : 1, "perm_fileuser" : 0, "perm_subcon" : 1 ',
 );

所以我的问题是:使用 SQL 更新语句,如何向我的 CLOB 添加另一个值,例如 "perm_bigboss" : 1?有没有使用 SQL 设置单个值 "perm_admin" : 0 的简单方法?

【问题讨论】:

看这里***.com/questions/41768597/… 【参考方案1】:

您可以使用JSON_OBJECT_TPUT 方法添加/设置单个值。

假设您更新单行(使用where 子句),您可以使用此块。如果有多行,请使用循环或游标。

 DECLARE
  v_pertags dmo_person.per_tags%TYPE;
  v_json_obj JSON_OBJECT_T;
  v_new_pertags dmo_person.per_tags%TYPE;
BEGIN
  SELECT per_tags
  INTO   v_pertags
  FROM   dmo_person; --where clause
  v_json_obj := TREAT(json_element_t.PARSE(v_pertags) AS json_object_t);
  v_json_obj.PUT('perm_bigboss' , 1);
  v_json_obj.PUT('perm_admin', 0);
  v_new_pertags := v_json_obj.to_string;

UPDATE dmo_person
  SET    per_tags = v_new_pertags; --where clause
END;
/ 

LIVESQL DEMO

【讨论】:

很好,谢谢!不知道我可以在 Oracle 文档中的什么地方找到它.. @Mockminister:不客气。请阅读:***.com/help/someone-answers JSON 文档 12.2 docs.oracle.com/en/database/oracle/oracle-database/12.2/adjsn/… 尤其是 PL/SQL docs.oracle.com/en/database/oracle/oracle-database/12.2/adjsn/…【参考方案2】:

对于 Oracle 11g 版本,不支持 Json 操作。所以我们必须使用基本函数:SUBSTR / INSTR / SUBSTR

create OR replace FUNCTION Get_Value(data_request VARCHAR2, s_key VARCHAR2) RETURN VARCHAR2
IS s_Value VARCHAR2(2000);

index1 integer := 0;
index2 integer := 0;

BEGIN 

s_Value := '';

SELECT INSTR(data_request, '"' || s_key || '":"' , 1, 1) INTO index1 FROM dual;

IF (index1 > 0) THEN
    index1 := index1 + LENGTH('"' || s_key || '":"') ;
    s_Value := SUBSTR(data_request, index1, LENGTH(data_request));
    SELECT INSTR(s_Value, '"', 1, 1) INTO index2 FROM dual;
    s_Value := SUBSTR(data_request, index1, index2-1);
END IF;

RETURN(s_Value); 

END;

假设,我们有一个表 'tableName',其列 'data_request like : "ip":"127.0.0.1","username":"userTest"

然后我们可以像这样解析 json 字符串:

SELECT data_request,  
Get_Value(data_request, 'numeroDeCompte'), Get_Value(data_request, 'ip') ip, 
Get_Value(data_request, 'username') username 
FROM tableName 

【讨论】:

以上是关于在 Oracle 中使用 SQL 操作 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSON_EXISTS Oracle SQL Developer 中使用双引号传递参数

多个节点同名时使用 Oracle SQL 获取 JSON_VALUE

在 Oracle PL/SQL 中,如何检查 JSON 对象是不是包含特定键的元素

从 Oracle PL/SQL 中的表生成 json 文件

Oracle 12c - 在 REST 调用中使用动态 SQL

oracle sql中的JSON_TABLE未捕获嵌套的json数据