当前位置:网站首页> mysql5.6解析JSON字符串方式(支持复杂的嵌套格式)
mysql5.6解析JSON字符串方式(支持复杂的嵌套格式)
2022-07-05 16:43:00 【1024问】
mysql5.6 解析JSON字符串
支持复杂的嵌套格式
mysql5.6及以下解析json方法
先说一下问题的背景
下面是对应的代码
mysql5.6 解析JSON字符串支持复杂的嵌套格式废话不多说,先上代码。
CREATE FUNCTION `json_parse`(`jsondata` longtext,`keyname` text) RETURNS text CHARSET utf8BEGINDECLARE delim VARCHAR(128);DECLAREresult longtext;DECLARE startpos INTEGER;DECLARE endpos INTEGER;DECLARE endpos1 INTEGER; DECLARE findpos INTEGER;DECLARE leftbrace INTEGER;DECLARE tmp longtext; DECLARE tmp2 longtext;DECLARE Flag INTEGER;SET delim = CONCAT('"', keyname, '": "');SET startpos = locate(delim,jsondata);IF startpos > 0 THENSET findpos = startpos+length(delim);SET leftbrace = 1;SET endpos = 0;SET Flag =1;get_token_loop: repeat IF substr(jsondata,findpos,2)='\\"' THENSET findpos = findpos + 2;iterate get_token_loop;ELSEIF substr(jsondata,findpos,2)='\\\\' THENSET findpos = findpos + 2;iterate get_token_loop;ELSEIF substr(jsondata,findpos,1)='"' AND Flag = 1 THEN SET endpos = findpos;SET findpos = LENGTH(jsondata)+1;leave get_token_loop;END IF;SET findpos = findpos + 1;UNTIL findpos > LENGTH(jsondata) END repeat;IF endpos > 0 THENSELECT substr(jsondata,startpos+length(delim)#取出value值的起始位置,endpos#取出value值的结束位置-(startpos+length(delim))#减去value值的起始位置,得到value值字符长度) INTO resultFROM DUAL;SET result= replace(result,'\\"','"');SET result= replace(result,'\\\\','\\');ELSE SET result=null;END IF;/*SELECT substr(jsondata,locate(delim,jsondata)+length(delim)#取出value值的起始位置,locate('"',jsondata,locate(delim,jsondata)+length(delim))#取出value值的结束位置-(locate(delim,jsondata)+length(delim))#减去value值的起始位置,得到value值字符长度) INTO resultFROM DUAL;*/ELSESET delim = CONCAT('"', keyname, '": {');SET startpos = locate(delim,jsondata);IF startpos > 0 THENSET findpos = startpos+length(delim);SET leftbrace = 0;SET endpos = 0;SET Flag =0;get_token_loop: repeat IF substr(jsondata,findpos,2)='{"' THENSET leftbrace = leftbrace + 1;SET findpos = findpos + 2;iterate get_token_loop;ELSEIF substr(jsondata,findpos,2)='\\"' THENSET findpos = findpos + 2;iterate get_token_loop;ELSEIF substr(jsondata,findpos,3)=': "' THENSET Flag = 1;SET findpos = findpos + 3;iterate get_token_loop;ELSEIF substr(jsondata,findpos,1)='"' THENSET Flag = 0;ELSEIF substr(jsondata,findpos,1)='}' AND Flag = 0 THENIF leftbrace > 0 THENSET leftbrace = leftbrace - 1;ELSE SET endpos = findpos;SET findpos = LENGTH(jsondata)+1;END IF;END IF;SET findpos = findpos + 1;UNTIL findpos > LENGTH(jsondata) END repeat;IF endpos > 0 THENSELECT substr(jsondata,startpos+length(delim)#取出value值的起始位置,endpos#取出value值的结束位置-(startpos+length(delim))#减去value值的起始位置,得到value值字符长度) INTO resultFROM DUAL;SET result=CONCAT("{",result, '}');ELSE SET result=null;END IF;ELSE SET delim = CONCAT('"', keyname, '": [');SET startpos = locate(delim,jsondata);IF startpos > 0 THENSET findpos = startpos+length(delim);SET leftbrace = 0;SET endpos = 0;SET tmp = substring_index(jsondata,delim,-1);SET tmp2 = substring_index(tmp,']',1); IF locate('[',tmp2) =0 THENSET endpos = locate(']',tmp);SET endpos = endpos+findpos-1; ELSEget_token_loop: repeat IF substr(jsondata,findpos,2)='\\"' THENSET findpos = findpos + 2;iterate get_token_loop;ELSEIF substr(jsondata,findpos,3)=': "' THENSET Flag = 1;SET findpos = findpos + 3;iterate get_token_loop;ELSEIF substr(jsondata,findpos,1)='[' AND Flag = 0 THENSET leftbrace = leftbrace + 1;SET findpos = findpos + 1;iterate get_token_loop;ELSEIF substr(jsondata,findpos,1)='"' THENSET Flag = 0;ELSEIF substr(jsondata,findpos,1)=']' AND Flag = 0 THENIF leftbrace > 0 THENSET leftbrace = leftbrace - 1;ELSE SET endpos = findpos;SET findpos = LENGTH(jsondata)+1;END IF;END IF;SET findpos = findpos + 1;UNTIL findpos > LENGTH(jsondata) END repeat;END IF;IF endpos > 0 THENSELECT substr(jsondata,startpos+length(delim)#取出value值的起始位置,endpos#取出value值的结束位置-(locate(delim,jsondata)+length(delim))#减去value值的起始位置,得到value值字符长度) INTO resultFROM DUAL;SET result=CONCAT("[",result, ']');ELSE SET result=null;END IF;ELSE SET delim = CONCAT('"', keyname, '": ');SET startpos = locate(delim,jsondata);IF startpos > 0 THENSET endpos = locate(',',jsondata,startpos+length(delim));SET endpos1 = locate('}',jsondata,startpos+length(delim));IF endpos>0 OR endpos1>0 THENIF endpos1>0 AND endpos1 < endpos OR endpos =0 THENSET endpos = endpos1;END IF;SELECT substr(jsondata,startpos+length(delim)#取出value值的起始位置,endpos#取出value值的结束位置-(locate(delim,jsondata)+length(delim))#减去value值的起始位置,得到value值字符长度) INTO resultFROM DUAL;IF STRCMP(result,'null')=0 THENSET result=null;END IF;ELSE SET result=null;END IF;ELSE SET result=null;END IF;END IF;END IF;END IF;if result='' and RIGHT(keyname,2)='Id' thenSET result=null;end if;RETURN result;ENDjsondata需要严格的json格式(注意逗号和分号以及双引号之间的空格)
SET jsondata='{"CurrentPage": 1, "data": [{"config": "123"}, {"config": "456"}], "PageSize": 10}' SELECT json_parse(jsondata, 'CurrentPage') INTO CurrentPage;SELECT json_parse(jsondata, 'data') INTO data;这边如果想获取config的内容,可以这样处理
SET count = (LENGTH(data)-LENGTH(REPLACE(data,'},','')))/2+1; SET i = 0; WHILE i < count DO SET SetObject = SUBSTRING_INDEX(SUBSTRING_INDEX(data,'},',i+1),'},',-1); IF LENGTH(SetObject)>0 THEN SELECT json_parse(SetObject, 'config') INTO config; END IF; SET i = i + 1; END WHILE;不足之处,jsondata数据多的情况下,会有效率问题。
mysql5.6及以下解析json方法之前在公司发现在线的查询平台是MySQL5.6,不能用JSON_EXTRACT,也不能用存储过程,所以只能自己编了一个简单的小查询,几条数据还是能查的,如果数据量大的话,估计耗的资源就会比较多。
先说一下问题的背景是想在'{"platform":"Android","source":"tt","details":null}'这一串东西里面找到source这个key对应的value值。
这个方法是先找到source":"这个字符串的起始位置和长度,这样就能够找到value值的起始位置;再找到这个字符串以后第一个"出现的位置,就能得到value值的结束位置。
再利用substr函数,就可以取出对应的位置。
下面是对应的代码SELECT '{"platform":"Android","source":"tt","details":null}' as 'sample',substr( '{"platform":"Android","source":"tt","details":null}' ,locate('source":"','{"platform":"Android","source":"tt","details":null}') +length('source":"')#取出value值的起始位置 ,locate( '"' ,'{"platform":"Android","source":"tt","details":null}' ,locate('source":"','{"platform":"Android","source":"tt","details":null}') +length('source":"') )#取出value值的结束位置 -( locate('source":"','{"platform":"Android","source":"tt","details":null}') +length('source":"') )#减去value值的起始位置,得到value值字符长度 ) as resultFROM DUAL 运行以后,就得到result的结果,就是tt。如果需要其他元素,就替换一下对应的key值和字段,就好了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。
边栏推荐
- Is it safe to open an account for digging wealth stocks? How is it safe to open a stock account?
- easyNmon使用汇总
- Embedded-c Language-4
- ECU简介
- Embedded UC (UNIX System Advanced Programming) -2
- 飞桨EasyDL实操范例:工业零件划痕自动识别
- Use byte stream to read Chinese from file to console display
- ThoughtWorks global CTO: build the architecture according to needs, and excessive engineering will only "waste people and money"
- 编译libssh2报错找不到openssl
- Judge whether a number is a prime number (prime number)
猜你喜欢
随机推荐
What else do you not know about new map()
winedt常用快捷键 修改快捷键latex编译按钮
Understand the usage of functions and methods in go language
ternary operator
Writing method of twig array merging
国内首家 EMQ 加入亚马逊云科技「初创加速-全球合作伙伴网络计划」
[wechat applet] read the life cycle and route jump of the applet
启牛商学院股票开户安全吗?靠谱吗?
Using C language to realize palindrome number
WR | 西湖大学鞠峰组揭示微塑料污染对人工湿地菌群与脱氮功能的影响
C# TCP如何设置心跳数据包,才显得优雅呢?
[729. My Schedule i]
【二叉树】根到叶路径上的不足节点
EasyX second lesson
Use of ThinkPHP template
[first lecture on robot coordinate system]
C#实现水晶报表绑定数据并实现打印3-二维码条形码
高数 | 旋转体体积计算方法汇总、二重积分计算旋转体体积
flask解决CORS ERR 问题
菜刀,蚁剑,冰蝎,哥斯拉的流量特征



![[729. My schedule I]](/img/e3/32914227d00cf7595ee850e60f2b72.png)




