数据库解析一维和二维简易JSON,

项目还在使用Oracle11,不支持后续官方的json解析方式, 在 前年、去年、今年 接连 遇到json解析问题后(其实是公司的轮子效率太慢,太复杂,决定自己造个轮子,看看到底为什么慢,是不是真的很复杂)

关于要不要自己再造轮子,其实还是比较犹豫的,后来不断遇到相似问题,才促使我自己搞一搞。

断断续续搞了1个礼拜多,算是初步有结果了。

至于说为什么JSON不放JAVA代码解析后再传数据库,项目总归是有各种各样的限制,以及人力物力的限制,不得不在数据库自己解析。

------------------------------------------------------------------------------------------------------------------------------

以上都是废话,

         如果你的JSON很复杂,请跳过本文。 这边只支持简易JSON。

        复杂JSON还未实现,也肯定不应该在数据库里处理 。

以下是代码实现

------------------------------------------------------------------------------------------------------------------------------

功能实现: json数组解析成sql语句,通过拼接sql可以执行

                已支持 字符串、数值、布尔值(转成1和0)、null;

实现方式:无循环嵌套,通过状态+队列来判断key和value ,最后使用sql语句,对数据进行整合

限制:1.由于表结构格式不一致,暂时没有实现value是 对象和数组的实现方式

           2. 目前使用场景还 比较单一,未作兼容性处理及错误判断.

正文

JSON数据:

[ { "key" : "valu e ","key2":"\\a\\\\\"","key3":4.43,"key4":true,"key5": null  },{"key5":Null,"key":"1","key3":0.02,"key4":false,"key2" : "2[{:," }] 

 生成代码:

SELECT *FROM (SELECT '1' AS KEY, '2[{:,' AS KEY2, 0.02 AS KEY3, 0 AS KEY4, NULL AS KEY5FROM DUALUNION ALLSELECT 'valu e ' AS KEY, '\\a\\\\\"' AS KEY2, 4.43 AS KEY3, 1 AS KEY4, NULL AS KEY5FROM DUAL) V_JSON


 生成代码查询:

查询效率:  大约0.09S

下面是代码, 使用Oracle来处理的,使用到的函数是 SUBSTR , LTRIM、 TRIM 、 LISTAGG

如果是其他数据库应该都有替代的函数, 稍微改下就可以用


DECLARE--字符串、数值、布尔值、null、对象和数组V_JSON VARCHAR2(2000) := ' [ { "key" : "valu e ","key2":"\\a\\\\\"","key3":4.43,"key4":true,"key5": null  },{"key5":Null,"key":"1","key3":0.02,"key4":false,"key2" : "2[{:," }] ';--不支持参数值是对象和数组的情况--V_JSON      VARCHAR2(2000) := ' [ { "key" : "valu e ","key2":"\\a\\\\\"","key3":4,"key4":true,"key5":[1,2,3,4]},{"key":"1","key3":2,"key4":false,"key2" : "2[{:,","key5":[342,3,2]}] ';V_LENGTH INT; --字符串总长度V_STR    VARCHAR2(10); --当前字符V_ZT     INT := -1; --状态 0 正常, -1 忽略V_STR_S VARCHAR2(10); --上一字符V_ZT_S  INT := -1; --上一字符 状态 0 正常, -1 忽略V_SQL     VARCHAR2(3000); --解析出来的SQLV_SQL_OUT VARCHAR2(3000); --输出语句 V_WORD    VARCHAR2(3000); --字符串key 或valueV_CHAT_TEMP VARCHAR2(3); --临时字符V_CHAT      VARCHAR2(3000); --字符栈,先进后出V_CHAT_ALL  VARCHAR2(3000); --所有字符V_I         NUMBER := 0;V_NUM_ARRYR NUMBER := 0; --数组序号V_NUM_KEY   NUMBER := 0; --key-value 序号
BEGIN--1. V_LENGTH := LENGTH(V_JSON);FOR V_I IN 1 .. V_LENGTH LOOPV_STR := SUBSTR(V_JSON, V_I, 1);--DBMS_OUTPUT.PUT_LINE(V_I || '=' || V_STR);--1.处理反斜杠IF (V_STR_S = '\' AND V_ZT_S = 0) THENV_STR_S := V_STR;V_ZT_S  := -1;V_WORD  := V_WORD || V_STR;CONTINUE;ELSEV_ZT := 0;END IF;--2.处理双引号IF SUBSTR(V_CHAT, 1, 1) = '"' THENV_WORD := V_WORD || V_STR;IF V_STR = '"' THENV_CHAT := SUBSTR(V_CHAT, 2, LENGTH(V_CHAT) - 1);--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);END IF;V_STR_S := V_STR;V_ZT_S  := V_ZT;CONTINUE;END IF;--上一个字符状态V_STR_S := V_STR;V_ZT_S  := V_ZT;IF V_STR = '{' THENV_CHAT     := V_STR || V_CHAT;V_CHAT_ALL := V_CHAT_ALL || V_STR;--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);ELSIF V_STR = '[' THENV_CHAT     := V_STR || V_CHAT;V_CHAT_ALL := V_CHAT_ALL || V_STR;--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);ELSIF V_STR = '}' THENV_CHAT     := SUBSTR(V_CHAT, 2, LENGTH(V_CHAT) - 1);V_CHAT_ALL := V_CHAT_ALL || V_STR;IF SUBSTR(V_CHAT_ALL, LENGTH(V_CHAT_ALL) - 1, 1) = ':' THENDBMS_OUTPUT.PUT_LINE('V_VALUE=' || V_WORD);V_SQL := V_SQL || ' UNION ALL SELECT ''' || V_WORD || ''' AS V ,' || V_NUM_KEY ||' AS N, 2 AS TYPE, ' || V_NUM_ARRYR || ' AS J  FROM DUAL';END IF;IF SUBSTR(V_CHAT, 1, 1) = '[' THENV_NUM_ARRYR := V_NUM_ARRYR + 1;END IF;V_NUM_KEY := 0;--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);ELSIF V_STR = ']' THENV_CHAT     := SUBSTR(V_CHAT, 2, LENGTH(V_CHAT) - 1);V_CHAT_ALL := V_CHAT_ALL || V_STR;--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);ELSIF V_STR = ':' THENV_CHAT_ALL := V_CHAT_ALL || V_STR;DBMS_OUTPUT.PUT_LINE('V_KEY=' || V_WORD);V_SQL  := V_SQL || ' UNION ALL SELECT ''' || V_WORD || ''' AS V ,' || V_NUM_KEY ||' AS N , 1 AS TYPE, ' || V_NUM_ARRYR || ' AS J  FROM DUAL';V_WORD := '';ELSIF V_STR = ',' THENV_CHAT_ALL := V_CHAT_ALL || V_STR;IF SUBSTR(V_CHAT_ALL, LENGTH(V_CHAT_ALL) - 1, 1) = ':' THENDBMS_OUTPUT.PUT_LINE('V_VALUE=' || V_WORD);V_SQL := V_SQL || ' UNION ALL SELECT ''' || V_WORD || ''' AS V ,' || V_NUM_KEY ||' AS N , 2 AS TYPE, ' || V_NUM_ARRYR || ' AS J  FROM DUAL';END IF;V_WORD := '';IF SUBSTR(V_CHAT, 1, 1) = '{' THENV_NUM_KEY := V_NUM_KEY + 1;END IF;ELSIF V_STR IN ('"') THENV_CHAT := V_STR || V_CHAT;V_WORD := V_WORD || V_STR;--DBMS_OUTPUT.PUT_LINE('V_CHAT=' || V_CHAT);V_WORD := V_STR;ELSIF V_STR IN (' ') THEN--  DBMS_OUTPUT.PUT_LINE('空格');V_STR_S := V_STR;ELSE V_WORD := V_WORD || V_STR;END IF;END LOOP;V_SQL := LTRIM(V_SQL, ' UNION ALL');--JSON结果转 输出语句V_SQL := ' WITH A AS ( ' || V_SQL || ' )
,b as (SELECT  A.J,A.N
, case when a_v.v like ''"%"'' then ''''''''|| substr(a_v.v,2,length(a_v.v)-2) || '''''''' else  case when TRIM(upper(a_v.v)) in ( ''TRUE'') THEN ''1'' when  TRIM(upper(a_v.v)) in ( ''FALSE'')  then ''0'' else a_v.v END end  as v_param 
,substr(a.v,2,length(a.v)-2)  as v_keyFROM A  LEFT JOIN A A_V ON A_V.N = A.N AND A_V.TYPE =2 AND A_V.J=A.J
WHERE  A.TYPE = 1  )
,c as (select  '' select '' || listagg( v_param ||'' as '' || v_key ,'','')  within group( order by v_key) || '' from dual '' as s 
from b  group by j  )
select ''SELECT * FROM ( ''||  listagg( c.s,'' union all '')  within group( order by null )  || '') V_JSON ''  as s 
from c ';EXECUTE IMMEDIATE V_SQLINTO V_SQL_OUT;DBMS_OUTPUT.PUT_LINE('V_SQL_OUT=');DBMS_OUTPUT.PUT_LINE(V_SQL_OUT);
END;

PS : 欢迎各个小伙伴积极交流  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/49688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【最新】cudnn安装教程

最近换了新电脑需要重新安装cuda和cudnn,发现现在cudnn的安装比以前方便多了,直接在官网下载exe安装包一键运行即可。安装的时候注意cuda和cudnn的对应关系即可:【最新】cuda和cudnn和显卡驱动的对应关系-CSDN博客 访问cudnn下载链接cuDNN 9…

Git 基础 GitHub【学习笔记】

一、Git 优势 大部分操作在本地完成,不需要联网完整性保证尽可能添加数据而不是删除或修改数据分支操作非常快捷流畅与 Linux 命令全面兼容 二、Git 程序安装 https://git-scm.com 三、Git 结构 #mermaid-svg-9Go6R1leWXWrDCqn {font-family:"trebuchet ms&quo…

运维锅总详解NFS

NFS是什么?如何对NFS进行部署及优化?NFS工作流程是什么?NFS的性能及优缺点是什么?NFS发展历史又是怎样的?希望本文能帮您解答这些疑惑! 一、NFS简介 NFS (Network File System) 是由 Sun Microsystems 在…

论文精读(保姆级解析)—— Flash Diffusion

0 前言 今天分析的论文是《Flash Diffusion: Accelerating Any Conditional Diffusion Model for Few Steps Image Generation》。该论文发表在2024年,目前已开源在arxiv上,主要提出了一种高效、快速且多功能的蒸馏方法,用于加速预训练扩散模…

[C++][STL源码剖析] 详解AVL树的实现

目录 1.概念 2.实现 2.1 初始化 2.2 插入 2.2.1 旋转(重点) 左单旋 右单旋 双旋 2.❗ 双旋后,对平衡因子的处理 2.3 判断测试 完整代码: 拓展:删除 1.概念 二叉搜索树虽可以缩短查找的效率,但…

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....

websocket 是一种双向通信协议,在建立连接后,websocket服务端和客户端都能主动向对方发送或者接收数据,而在http协议中,一个request只能有一个response,而且这个response也是被动的,不能主动发起。 websoc…

【研路导航】保研英语面试高分攻略,助你一路过关斩将

面试攻略之 千锤百炼英语口语 写在前面 在保研面试中,英语口语往往是让许多同学感到头疼的一部分。如何在面试中展现出自信和流利的英语表达能力,是我们今天要探讨的主题。以下是一些有效的英语口语练习方法和常见题型解析,帮助你在保研面试…

LoRA:低秩自适应

LoRA:低秩自适应 本章节是对轻松上手微调大语言模型——QLORA篇中提到的LoRA的原理解释。 背后动机 现今模型的参数量变得越来越大,对预训练模型进行全微调变得越来越不可行。为了解决这个问题有了LoRA(Low-Rank Adaption)的诞生。将可训练…

Nginx制作下载站点

使用nginx制作一个类似nginx官网的下载站点 如何制作一个下载站点,首先需要ngx_http_autoindex_module模块 该模块处理以斜杠(“/”)结尾的请求,并生成目录列表。 nginx编译的时候会自动加载该模块,但是该模块默认是关闭的,需要使用下来指令…

3 FreeRTOS移植(从FREERTOS官网移植进自己的工程)

3 FreeRTOS移植 1 获取FreeRTOS源码(熟悉)1.1 介绍源码内容1.2 FreeRTOS内核1.2.1 Demo文件夹1.2.2 Source文件夹1.2.2.1 portable文件夹 2 FreeRTOS手把手移植(掌握)(重要)2.1 移植步骤 3 系统配置文件说明…

GraphHopper-map-navi_路径规划、导航(web前端页面版)

文章目录 一、项目地址二、踩坑环境三、问题记录3.1、graphhopper中地图问题3.1.1. getOpacity不存在的问题3.1.2. dispatchEvent不存在的问题3.1.3. vectorLayer.set(background-maplibre-layer, true)不存在set方法3.1.4. maplibre-gl.js.map不存在的问题3.1.5. Uncaught Ref…

学习记录:ESP32控制舵机 FREERTOS BLE

控制舵机 PWM信号 PWM信号是一种周期性变化的方波信号,它有两个关键参数: 周期(Period):一个完整的PWM信号的时间长度,通常用秒(s)或毫秒(ms)表示。占空比…

FFmpeg解复用器如何从封装格式中解析出不同的音视频数据

目录 1、ffmpeg介绍 2、FFMPEG的目录结构 3、FFmpeg的格式封装与分离 3.1、数据结构 3.2、封装和分离(muxer和demuxer) 3.2.1、Demuxer流程 3.2.2、Muxer流程 4、总结 4.1、播放器 4.2、转码器 C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续…

微服务上(黑马)

文章目录 微服务011 认识微服务1.1 单体架构1.2 微服务1.3 SpringCloud 2 微服务拆分2.1 熟悉黑马商城2.2 服务拆分原则2.2.1.什么时候拆2.2.2.怎么拆 2.3 拆分服务2.3.1 拆分商品管理功能模块2.3.2 拆分购物车功能模块 2.4 远程调用2.4.1 RestTemplate2.4.2.远程调用 2.5 总结…

顺序表算法题

在学习了顺序表专题后,了解的顺序表的结构以及相关概念后就可以来试着完成一些顺序表的算法题了,在本篇中将对三道顺序表相关的算法题进行讲解,希望能对你有所帮助,一起加油吧!!! 1.移除元素 2…

nginx转发netty长链接(nginx负载tcp长链接配置)

首先要清楚一点,netty是长链接是tcp连接不同于http中负载在http中配置server监听。长连接需要开启nginx的stream模块(和http是并列关系) 安装nginx时注意开启stream,编译时加上参数 --with-stream (其他参数根据自己所需来加) …

脊髓损伤的小伙伴锻炼贴士

Hey小伙伴们~👋 今天要跟大家聊一个超燃又超温馨的话题!🌟 对于我们脊髓损伤的小伙伴们来说,保持身体活力,不仅是健康的小秘诀,更是拥抱美好生活的超能量哦!💪 #脊髓损伤# 首先&…

Cache 替换策略--PLRU算法详解

一、引言 LRU(Least Recently Used)是 cache 的经典替换策略之一,但当 Cache 的路数比较大时(多路组相连结构),实现 LRU 的硬件开销就会变得很大。现代处理器一般会考虑使用 PLRU(pseudo-LRU&a…

一文带你搞懂C++运算符重载

7. C运算符重载 C运算符重载 什么是运算符重载 运算符重载赋予运算能够操作自定义类型。 运算符重载前提条件: 必定存在一个自定义类型 运算符重载实质: 就是函数调用 友元重载 类重载 在同一自定义类型中,一个运算符只能被重载一次 C重载只能重载…