mysql5.6|mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)

目录

  • mysql5.6 解析JSON字符串
    • 支持复杂的嵌套格式
  • mysql5.6及以下解析json方法
    • 先说一下问题的背景
    • 下面是对应的代码

mysql5.6 解析JSON字符串
支持复杂的嵌套格式
废话不多说,先上代码。
CREATE FUNCTION `json_parse`(`jsondata` longtext,`keyname` text) RETURNS text CHARSET utf8BEGIN DECLARE delim VARCHAR(128); DECLARE result 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 = 1THEN 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 = 0THENIF 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 = 0THENIF 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; ELSESET 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; ELSESET result=null; END IF; ELSESET result=null; END IF; END IF; END IF; END IF; if result='' and RIGHT(keyname,2)='Id' thenSET result=null; end if; RETURN result; END

jsondata需要严格的json格式(注意逗号和分号以及双引号之间的空格)
SET jsondata='https://www.it610.com/article/{"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 DOSET SetObject = SUBSTRING_INDEX(SUBSTRING_INDEX(data,'},',i+1),'},',-1); IF LENGTH(SetObject)>0 THENSELECT 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值和字段,就好了。
【mysql5.6|mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读