Home > Database > Mysql Tutorial > body text

How to use mysql5.6 to parse JSON strings

王林
Release: 2023-05-31 12:04:06
forward
2270 people have browsed it

mysql5.6 解析JSON字符串

支持复杂的嵌套格式

废话不多说,先上代码。

CREATE FUNCTION `json_parse`(`jsondata` longtext,`keyname` text) RETURNS text CHARSET utf8
BEGIN
	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 THEN
		SET findpos = startpos+length(delim);
		SET leftbrace = 1;
		SET endpos = 0;
		SET Flag =1;
		get_token_loop: repeat 
				IF substr(jsondata,findpos,2)='\\"' THEN
					SET findpos = findpos + 2;
					iterate get_token_loop;
				ELSEIF substr(jsondata,findpos,2)='\\\\' THEN
					SET 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 THEN
				SELECT 
					substr(
						jsondata
						,startpos
						+length(delim)#取出value值的起始位置
						,endpos#取出value值的结束位置
						-(
							startpos
							+length(delim)
							)#减去value值的起始位置,得到value值字符长度
					) INTO result
				FROM 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 result
		FROM DUAL;	*/
	ELSE
			SET delim = CONCAT('"', keyname, '": {');
			SET startpos = locate(delim,jsondata);
			IF startpos > 0 THEN
				SET findpos = startpos+length(delim);
				SET leftbrace = 0;
				SET endpos = 0;
				SET Flag =0;
	
			get_token_loop: repeat 
					IF substr(jsondata,findpos,2)='{"' THEN
						SET leftbrace = leftbrace + 1;
						SET findpos = findpos + 2;
						iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,2)='\\"' THEN
						SET findpos = findpos + 2;
						iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,3)=': "' THEN
							SET Flag = 1;
							SET findpos = findpos + 3;
							iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,1)='"' THEN
						SET Flag = 0;
					ELSEIF substr(jsondata,findpos,1)='}' AND Flag = 0  THEN
						IF leftbrace > 0 THEN
							SET 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 THEN
					SELECT 
						substr(
							jsondata
							,startpos
							+length(delim)#取出value值的起始位置
							,endpos#取出value值的结束位置
							-(
								startpos
								+length(delim)
								)#减去value值的起始位置,得到value值字符长度
						) INTO result
					FROM DUAL;
					SET result=CONCAT("{",result, '}');
				ELSE 
					SET result=null;
				END IF;
			ELSE 
				SET delim = CONCAT('"', keyname, '": [');
				SET startpos = locate(delim,jsondata);
				IF startpos > 0 THEN
					SET 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 THEN					
							SET endpos = locate(']',tmp);
							SET endpos = endpos+findpos-1;
					 ELSE
							get_token_loop: repeat 
									IF substr(jsondata,findpos,2)='\\"' THEN
										SET findpos = findpos + 2;
										iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,3)=': "' THEN
											SET Flag = 1;
											SET findpos = findpos + 3;
											iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,1)='[' AND Flag = 0 THEN
										SET leftbrace = leftbrace + 1;
										SET findpos = findpos + 1;
										iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,1)='"' THEN
										SET Flag = 0;
									ELSEIF substr(jsondata,findpos,1)=']' AND Flag = 0  THEN
										IF leftbrace > 0 THEN
											SET 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 THEN
						SELECT 
							substr(
								jsondata
								,startpos
								+length(delim)#取出value值的起始位置
								,endpos#取出value值的结束位置
								-(
									locate(delim,jsondata)
									+length(delim)
									)#减去value值的起始位置,得到value值字符长度
							) INTO result
						FROM DUAL;
						SET result=CONCAT("[",result, ']');
					ELSE 
						SET result=null;
					END IF;
				ELSE 					
					SET delim = CONCAT('"', keyname, '": ');
					SET startpos = locate(delim,jsondata);
					IF startpos > 0 THEN
						SET endpos = locate(',',jsondata,startpos+length(delim));
						SET endpos1 = locate('}',jsondata,startpos+length(delim));
						IF endpos>0 OR endpos1>0 THEN
								IF endpos1>0 AND endpos1 < endpos OR endpos =0 THEN
									SET endpos = endpos1;
								END IF;
								SELECT 
									substr(
										jsondata
										,startpos
										+length(delim)#取出value值的起始位置
										,endpos#取出value值的结束位置
										-(
											locate(delim,jsondata)
											+length(delim)
											)#减去value值的起始位置,得到value值字符长度
									) INTO result
								FROM DUAL;
								
								IF STRCMP(result,&#39;null&#39;)=0 THEN
									SET result=null;
								END IF;
						ELSE 					
							SET result=null;
						END IF;
					ELSE 					
						SET result=null;
					END IF;
				END IF;
			END IF;
	END IF;
	if result=&#39;&#39; and RIGHT(keyname,2)=&#39;Id&#39; then
		SET result=null;
	end if;
	RETURN result;
END
Copy after login

jsondata需要严格的json格式(注意逗号和分号以及双引号之间的空格)

SET jsondata=&#39;{"CurrentPage": 1, "data": [{"config": "123"}, {"config": "456"}], "PageSize": 10}&#39; 
SELECT json_parse(jsondata, &#39;CurrentPage&#39;) INTO CurrentPage;
SELECT json_parse(jsondata, &#39;data&#39;) INTO data;
Copy after login

这边如果想获取config的内容,可以这样处理

        SET count = (LENGTH(data)-LENGTH(REPLACE(data,&#39;},&#39;,&#39;&#39;)))/2+1;
        SET i = 0;
        WHILE i < count DO
            SET SetObject = SUBSTRING_INDEX(SUBSTRING_INDEX(data,&#39;},&#39;,i+1),&#39;},&#39;,-1);
            IF LENGTH(SetObject)>0 THEN
                SELECT json_parse(SetObject, &#39;config&#39;) INTO config;    
            END IF;
            SET i = i + 1;
        END WHILE;
Copy after login

不足之处,jsondata数据多的情况下,会有效率问题。

mysql5.6及以下解析json方法

之前在公司发现在线的查询平台是MySQL5.6,不能用JSON_EXTRACT,也不能用存储过程,所以只能自己编了一个简单的小查询,几条数据还是能查的,如果数据量大的话,估计耗的资源就会比较多。

先说一下问题的背景

是想在'{"platform":"Android","source":"tt","details":null}'这一串东西里面找到source这个key对应的value值。

这个方法是先找到source":"这个字符串的起始位置和长度,这样就能够找到value值的起始位置;再找到这个字符串以后第一个"出现的位置,就能得到value值的结束位置。

再利用substr函数,就可以取出对应的位置。

下面是对应的代码

SELECT 
&#39;{"platform":"Android","source":"tt","details":null}&#39; as &#39;sample&#39;
,substr(
  &#39;{"platform":"Android","source":"tt","details":null}&#39;
  ,locate(&#39;source":"&#39;,&#39;{"platform":"Android","source":"tt","details":null}&#39;)
   +length(&#39;source":"&#39;)#取出value值的起始位置
  ,locate(
  		&#39;"&#39;
  		,&#39;{"platform":"Android","source":"tt","details":null}&#39;
  		,locate(&#39;source":"&#39;,&#39;{"platform":"Android","source":"tt","details":null}&#39;)
  		+length(&#39;source":"&#39;)
  		)#取出value值的结束位置
	  -(
	  	locate(&#39;source":"&#39;,&#39;{"platform":"Android","source":"tt","details":null}&#39;)
	  	+length(&#39;source":"&#39;)
	  	)#减去value值的起始位置,得到value值字符长度
  ) as result
FROM DUAL
Copy after login

运行以后,就得到result的结果,就是tt。如果需要其他元素,就替换一下对应的key值和字段,就好了。

The above is the detailed content of How to use mysql5.6 to parse JSON strings. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template