Oracle解析复杂json的方法实例详解

 更新时间:2017年05月05日 08:53:58   作者:漠北雁  
这篇文章主要介绍了Oracle解析复杂json的方法,本文给大家带来两种方法解决此问题,需要的朋友可以参考下

问题背景:

         当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的PLSQL脚本大多也只可以解析结构较单一的json串,对于结构复杂的json串还无法解析。如此一来导致即便可以在PL/SQL中调用远程接口,但返回结果仍需传给前台js或java等其它代码进行处理,不太方便。

分析思路:

         1、在PL/SQL中写json串,无需声明json对象,只需直接拼接成格式正确的json字符串即可,因此数据库对象间json串的传递完全可以用varchar2或clob来代替。

         2、结构复杂的json串节点元素值基本上可以分为两类:①仍为json串②json数组,因此我们只需对这两种类型的json对象进行处理即可。

         3、在PL/SQL中处理json数组时,由于json元素是无序且可以重复的,因此我们需要对数组成员进行索引并能够获取数组长度才可以对其循环处理。

         4、java中有很多可以方便解析json串的开源jar包,且数据库支持导入java类文件,因此是否可以将java代码编译生成的class导入数据处理json呢?

解决方案:

方法1:loadjava导入java类进行解析

1、查看当前数据库已导入的java类文件

2、执行loadjava命令导入处理json所需jar文件,在此选择org.json而不选择fastjson或jackson的原因是该jar包没有外部依赖且满足功能的同时所需导入类文件较少。

--向数据库导入json相关jar包
loadjava -r -f -u scott/tiger@xxx.xxx.xxx.xxx:1521/orcl json.jar
--删除指定jar
#dropjava -u scott/tiger@xxx.xxx.xxx.xxx:1521/orcl json.jar

在此,我们执行导入,如下:

细节:如果导入的jar包存在外部依赖,会报如下异常,继续导入外部依赖只会使要导入的jar包越来越多,最终还不一定可以导入成功,得不偿失,如下:

3、导入json.jar成功后再次查看当前已导入的类文件如下

4、在数据库SQL窗口执行以下脚本,创建java源码对象

create or replace and compile java source named "JsonUtil" as
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.Integer;
public class JsonUtil {
 //取json串单个节点值
 public static String getValue(String jsonStr,String nodeName){
 String nodeValue="";
 try {
  if(jsonStr==null||!jsonStr.startsWith("{")||!jsonStr.endsWith("}")){
  nodeValue="";
  }else{
  JSONObject obj =new JSONObject(jsonStr);
  nodeValue = obj.getString(nodeName);
  }
 } catch (JSONException e) {
  nodeValue="";
 }
 return nodeValue;
 }
 //取json数组长度便于循环处理
 public static Integer getArrayLength(String jsonArrayStr){
 Integer length=0;
 try {
  if(jsonArrayStr==null||!jsonArrayStr.startsWith("[")||!jsonArrayStr.endsWith("]")){
  length=0;
  }else{
  JSONArray jsonArr = new JSONArray(jsonArrayStr);
  length=jsonArr.length();
  }
 } catch (JSONException e) {
  length=0;
 }
 return length;
 }
 //取json数组第index个元素
 public static String getArrayValue(String jsonStr,Integer index){
 String nodeValue="";
 try {
  if(jsonStr==null||!jsonStr.startsWith("[")||!jsonStr.endsWith("]")){
  nodeValue="";
  }else{
  JSONArray jsonArr = new JSONArray(jsonStr);
  nodeValue=jsonArr.getString(index);
  }
 } catch (JSONException e) {
  nodeValue="";
 }
 return nodeValue;
 }
}

创建成功后再次查询可以看到对应的class文件:

5、利用步骤4创建的class创建function(或procedure),在此为了使其跟目前数据库已存在的json处理方法区分开,我们创建一个package,如下:

create or replace package jsonpkg
as
function getval(jsonstr varchar2,nodename varchar2) return varchar2;
function getarrval(jsonArrayStr varchar2,seqNo number) return varchar2;
function getarrlen(jsonArrayStr varchar2) return number;
end jsonpkg;
/
create or replace package body jsonpkg
as
function getval(jsonstr varchar2,nodename varchar2) return varchar2
as language java name 'JsonUtil.getValue(java.lang.String,java.lang.String) return java.lang.String';
function getarrval(jsonArrayStr varchar2,seqNo number) return varchar2
as language java name 'JsonUtil.getArrayValue(java.lang.String, java.lang.Integer) return java.lang.String';
function getarrlen(jsonArrayStr varchar2) return number
as language java name 'JsonUtil.getArrayLength(java.lang.String) return java.lang.Integer';
end jsonpkg;
/

创建成功后可以查看包说明和主体:

6、测试

①简单json测试

②解析复杂json

至此,我们就可以很轻松的就取到json串中任意节点的值(如果节点值为数组则可以先计算数组长度再进行loop循环处理,或直接用getarrval方法取指定数组元素的值)。

方法2:安装开源组件PL/JSON

下载地址: https://github.com/pljson/pljson

优点:安装方便,解析方法较专业;缺点:新增数据库对象较多,短期学习成本较高。文档很详细,在此不再赘述。如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • Oracle表空间不足的两种解决办法

    Oracle表空间不足的两种解决办法

    这篇文章主要介绍了Oracle表空间不足的两种解决办法,需要的朋友可以参考下
    2017-10-10
  • Oracle 中 decode 函数用法

    Oracle 中 decode 函数用法

    这篇文章主要介绍了Oracle 中 decode 函数用法的相关资料,需要的朋友可以参考下
    2017-10-10
  • Oracle 细粒度审计(FGA)初步认识

    Oracle 细粒度审计(FGA)初步认识

    细粒度审计(FGA),是在Oracle 9i中引入的,能够记录SCN号和行级的更改以重建旧的数据,本文将详细介绍,需要的朋友可以参考下
    2012-12-12
  • Oracle修改表空间大小的方法

    Oracle修改表空间大小的方法

    这篇文章主要介绍了Oracle修改表空间大小的方法,实例讲述了Oracle通过命令行实现修改Oracle表空间大小的方法,非常简单实用,需要的朋友可以参考下
    2015-12-12
  • Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例

    Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例

    这篇文章主要介绍了Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例,包含代码实例,而且小编已经测试过了哦,需要的朋友可以参考下
    2014-07-07
  • Oracle临时表空间删除和重建实现过程

    Oracle临时表空间删除和重建实现过程

    这篇文章主要介绍了Oracle临时表空间删除和重建实现过程,临时表空间是NOLOGGING模式以及它不保存永久类型对象,因此即使数据库损毁,做Recovery也不需要恢复Temporary Tablespace。下文更多详细内容介绍需要的小伙伴可以参考一下
    2022-03-03
  • Linux一键部署oracle安装环境脚本(推荐)

    Linux一键部署oracle安装环境脚本(推荐)

    这篇文章主要介绍了Linux一键部署oracle安装环境脚本,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • PLSQL安装、汉化和激活的方法步骤实现

    PLSQL安装、汉化和激活的方法步骤实现

    这篇文章主要介绍了PLSQL安装、汉化和激活的方法步骤实现,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Oracle Max函数使用中出现的问题

    Oracle Max函数使用中出现的问题

    在Oracle Max函数使用中,会出现一些问题,本文将介绍解决方法,需要的朋友可以了解下
    2012-11-11
  • Oracle数据库时间格式转换的常见示例

    Oracle数据库时间格式转换的常见示例

    这篇文章主要给大家介绍了关于Oracle数据库时间格式转换的常见示例,在实际的工作中会经常会用到to_char()、to_date()函数来对时间、日期进行处理,文中给出了详细的代码示例,需要的朋友可以参考下
    2024-02-02

最新评论