目次
mysql5.6 解析JSON字符串
支持复杂的嵌套格式
mysql5.6及以下解析json方法
先说一下问题的背景
下面是对应的代码 
ホームページ データベース mysql チュートリアル mysql5.6 を使用して JSON 文字列を解析する方法

mysql5.6 を使用して JSON 文字列を解析する方法

May 31, 2023 pm 12:04 PM
mysql json

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,'null')=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='' and RIGHT(keyname,2)='Id' then
		SET result=null;
	end if;
	RETURN result;
END
ログイン後にコピー

jsondata需要严格的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 result
FROM DUAL
ログイン後にコピー

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

以上がmysql5.6 を使用して JSON 文字列を解析する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPのビッグデータ構造処理スキル PHPのビッグデータ構造処理スキル May 08, 2024 am 10:24 AM

PHPのビッグデータ構造処理スキル

PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? Jun 03, 2024 pm 08:11 PM

PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか?

PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? Jun 03, 2024 pm 12:19 PM

PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか?

PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? Jun 02, 2024 pm 02:26 PM

PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか?

データベースにおける Java 列挙型のアプリケーション シナリオは何ですか? データベースにおける Java 列挙型のアプリケーション シナリオは何ですか? May 05, 2024 am 09:06 AM

データベースにおける Java 列挙型のアプリケーション シナリオは何ですか?

Jackson ライブラリのアノテーションは、JSON のシリアル化と逆シリアル化をどのように制御しますか? Jackson ライブラリのアノテーションは、JSON のシリアル化と逆シリアル化をどのように制御しますか? May 06, 2024 pm 10:09 PM

Jackson ライブラリのアノテーションは、JSON のシリアル化と逆シリアル化をどのように制御しますか?

MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 Dec 09, 2024 am 11:42 AM

MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法

PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? Jun 02, 2024 pm 02:13 PM

PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか?

See all articles