SQL操作Json数据
转载自: http://blog.csdn.net/yapingxin/article/details/16913275
有小改动..
支持复杂结构的使用..
使用Parent_ID来对应Object_ID产生关系就好..
实现对Json数据的从文字到表变量的转换..
例:
[
{
"FieldName": "DateKey",
"Title": "汇总后日期",
"Description": "",
"DataType": 4,
"DataGroup": 0,
"SumMethod": 0,
"DataSumField": "",
"MaxLenght": 100,
"IsAllowNull": false,
"UnionFieldName": "",
"SortID": -99,
"IsSourceField": true,
"IsLabelSearch": true,
"IsPartition": true,
"IsSQLBSumField": true
},
{
"FieldName": "MemberNumber",
"Title": "会员卡编号",
"Description": "",
"DataType": 2,
"DataGroup": 0,
"SumMethod": 0,
"DataSumField": "",
"MaxLenght": 100,
"IsAllowNull": false,
"UnionFieldName": "",
"SortID": 0,
"IsSourceField": true,
"IsLabelSearch": false,
"IsPartition": false,
"IsSQLBSumField": true
},
{
"FieldName": "PageNo",
"Title": "频道页编号",
"Description": "",
"DataType": 2,
"DataGroup": 0,
"SumMethod": 0,
"DataSumField": "",
"MaxLenght": 100,
"IsAllowNull": false,
"UnionFieldName": "",
"SortID": 1,
"IsSourceField": true,
"IsLabelSearch": true,
"IsPartition": false,
"IsSQLBSumField": true
}
]
Declare @str nvarchar(max)
set @str='上边的Json字符串'
Select * from parseJSON(@str)

--下边的函数..执行就好.. SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO IF NOT EXISTS(
select * from sys.objects where
object_id = OBJECT_ID(N'dbo.ParseJSON') AND
type in (N'FN', N'IF', N'TF', N'FS', N'FT', N'F'))
BEGIN
EXEC('CREATE FUNCTION dbo.ParseJSON() RETURNS @hierarchy table( id int ) AS BEGIN RETURN END;');
PRINT 'FUNCTION dbo.ParseJSON is created.';
END GO
ALTER FUNCTION [dbo].[ParseJSON]( @json nvarchar(max) )
RETURNS @hierarchy table
(
object_id int NOT NULL, /* [0 -- Not an object] each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */
parent_id int NOT NULL, /* [0 -- Root] if the element has a parent then it is in this column. The document is the ultimate parent, so you can get the structure from recursing from the document */
name nvarchar(2000), /* the name of the object */
stringvalue nvarchar(4000) NOT NULL, /*the string representation of the value of the element. */
valuetype nvarchar(100) NOT NULL, /* the declared type of the value represented as a string in stringvalue*/
bigintvalue bigint,
boolvalue bit
) AS BEGIN
DECLARE
@firstobject int, --the index of the first open bracket found in the JSON string
@opendelimiter int, --the index of the next open bracket found in the JSON string
@nextopendelimiter int,--the index of subsequent open bracket found in the JSON string
@nextclosedelimiter int,--the index of subsequent close bracket found in the JSON string
@type nvarchar(10),--whether it denotes an object or an array
@nextclosedelimiterChar CHAR(1),--either a '}' or a ']'
@contents nvarchar(MAX), --the unparsed contents of the bracketed expression
@start int, --index of the start of the token that you are parsing
@end int,--index of the end of the token that you are parsing
@param int,--the parameter at the end of the next Object/Array token
@endofname int,--the index of the start of the parameter at end of Object/Array token
@token nvarchar(4000),--either a string or object
@value nvarchar(MAX), -- the value as a string
@name nvarchar(200), --the name as a string
@parent_id int,--the next parent ID to allocate
@lenjson int,--the current length of the JSON String
@characters NCHAR(62),--used to convert hex to decimal
@result BIGINT,--the value of the hex symbol being parsed
@index SMALLINT,--used for parsing the hex value
@escape int; --the index of the next escape character /* in this temporary table we keep all strings, even the names of the elements, since they are 'escaped'
* in a different way, and may contain, unescaped, brackets denoting objects or lists. These are replaced in
* the JSON string by tokens representing the string
*/
DECLARE @strings table
(
string_id int IDENTITY(1, 1),
stringvalue nvarchar(MAX)
) /* initialise the characters to convert hex to ascii */
SET @characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET @parent_id = 0; /* firstly we process all strings. This is done because [{} and ] aren't escaped in strings, which complicates an iterative parse. */
WHILE 1 = 1 /* forever until there is nothing more to do */
BEGIN
SET @start = PATINDEX('%[^a-zA-Z]["]%', @json collate SQL_Latin1_General_CP850_Bin); /* next delimited string */ IF @start = 0 BREAK; /*no more so drop through the WHILE loop */ IF SUBSTRING(@json, @start+1, 1) = '"'
BEGIN /* Delimited name */
SET @start = @start+1;
SET @end = PATINDEX('%[^\]["]%', RIGHT(@json, LEN(@json+'|')-@start) collate SQL_Latin1_General_CP850_Bin);
END IF @end = 0 /*no end delimiter to last string*/
BREAK; /* no more */ SELECT @token = SUBSTRING(@json, @start+1, @end-1) /* now put in the escaped control characters */
SELECT @token = REPLACE(@token, from_string, to_string)
FROM
(
SELECT '\"' AS from_string, '"' AS to_string
UNION ALL
SELECT '\\', '\'
UNION ALL
SELECT '\/', '/'
UNION ALL
SELECT '\b', CHAR(08)
UNION ALL
SELECT '\f', CHAR(12)
UNION ALL
SELECT '\n', CHAR(10)
UNION ALL
SELECT '\r', CHAR(13)
UNION ALL
SELECT '\t', CHAR(09)
) substitutions; SET @result = 0;
SET @escape = 1; /*Begin to take out any hex escape codes*/
WHILE @escape > 0
BEGIN /* find the next hex escape sequence */
SET @index = 0;
SET @escape = PATINDEX('%\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%', @token collate SQL_Latin1_General_CP850_Bin); IF @escape > 0 /* if there is one */
BEGIN WHILE @index < 4 /* there are always four digits to a \x sequence */
BEGIN
/* determine its value */
SET @result = @result + POWER(16, @index) * (CHARINDEX(SUBSTRING(@token, @escape + 2 + 3 - @index, 1), @characters) - 1);
SET @index = @index + 1;
END /* and replace the hex sequence by its unicode value */
SET @token = STUFF(@token, @escape, 6, NCHAR(@result));
END END /* now store the string away */
INSERT INTO @strings (stringvalue) SELECT @token; /* and replace the string with a token */
SET @json = STUFF(@json, @start, @end + 1, '@string' + CONVERT(nvarchar(5), @@identity)); END /* all strings are now removed. Now we find the first leaf. */
WHILE 1 = 1 /* forever until there is nothing more to do */
BEGIN SET @parent_id = @parent_id + 1; /* find the first object or list by looking for the open bracket */
SET @firstobject = PATINDEX('%[{[[]%', @json collate SQL_Latin1_General_CP850_Bin); /*object or array*/ IF @firstobject = 0 BREAK; IF (SUBSTRING(@json, @firstobject, 1) = '{')
SELECT @nextclosedelimiterChar = '}', @type = 'object';
ELSE
SELECT @nextclosedelimiterChar = ']', @type = 'array'; SET @opendelimiter = @firstobject; WHILE 1 = 1 --find the innermost object or list...
BEGIN
SET @lenjson = LEN(@json+'|') - 1; /* find the matching close-delimiter proceeding after the open-delimiter */
SET @nextclosedelimiter = CHARINDEX(@nextclosedelimiterChar, @json, @opendelimiter + 1); /* is there an intervening open-delimiter of either type */
SET @nextopendelimiter = PATINDEX('%[{[[]%',RIGHT(@json, @lenjson-@opendelimiter) collate SQL_Latin1_General_CP850_Bin); /*object*/ IF @nextopendelimiter = 0 BREAK; SET @nextopendelimiter = @nextopendelimiter + @opendelimiter; IF @nextclosedelimiter < @nextopendelimiter BREAK; IF SUBSTRING(@json, @nextopendelimiter, 1) = '{'
SELECT @nextclosedelimiterChar = '}', @type = 'object';
ELSE
SELECT @nextclosedelimiterChar = ']', @type = 'array'; SET @opendelimiter = @nextopendelimiter;
END /* and parse out the list or name/value pairs */
SET @contents = SUBSTRING(@json, @opendelimiter+1, @nextclosedelimiter-@opendelimiter - 1); SET @json = STUFF(@json, @opendelimiter, @nextclosedelimiter - @opendelimiter + 1, '@' + @type + CONVERT(nvarchar(5), @parent_id)); WHILE (PATINDEX('%[A-Za-z0-9@+.e]%', @contents collate SQL_Latin1_General_CP850_Bin)) < > 0
BEGIN /* WHILE PATINDEX */ IF @type = 'object' /*it will be a 0-n list containing a string followed by a string, number,boolean, or null*/
BEGIN SET @end = CHARINDEX(':', ' '+@contents); /*if there is anything, it will be a string-based name.*/
SET @start = PATINDEX('%[^A-Za-z@][@]%', ' ' + @contents collate SQL_Latin1_General_CP850_Bin); /*AAAAAAAA*/ SET @token = SUBSTRING(' '+@contents, @start + 1, @end - @start - 1);
SET @endofname = PATINDEX('%[0-9]%', @token collate SQL_Latin1_General_CP850_Bin);
SET @param = RIGHT(@token, LEN(@token)-@endofname + 1); SET @token = LEFT(@token, @endofname - 1);
SET @contents = RIGHT(' ' + @contents, LEN(' ' + @contents + '|') - @end - 1); SELECT @name = stringvalue FROM @strings WHERE string_id = @param; /*fetch the name*/ END
ELSE
BEGIN
SET @name = null;
END SET @end = CHARINDEX(',', @contents); /*a string-token, object-token, list-token, number,boolean, or null*/ IF @end = 0
SET @end = PATINDEX('%[A-Za-z0-9@+.e][^A-Za-z0-9@+.e]%', @contents+' ' collate SQL_Latin1_General_CP850_Bin) + 1; SET @start = PATINDEX('%[^A-Za-z0-9@+.e][A-Za-z0-9@+.e]%', ' ' + @contents collate SQL_Latin1_General_CP850_Bin); /*select @start,@end, LEN(@contents+'|'), @contents */ SET @value = RTRIM(SUBSTRING(@contents, @start, @end-@start));
SET @contents = RIGHT(@contents + ' ', LEN(@contents+'|') - @end); IF SUBSTRING(@value, 1, 7) = '@object'
INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype)
SELECT @name, @parent_id, SUBSTRING(@value, 8, 5), SUBSTRING(@value, 8, 5), 'object'; ELSE
IF SUBSTRING(@value, 1, 6) = '@array'
INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype)
SELECT @name, @parent_id, SUBSTRING(@value, 7, 5), SUBSTRING(@value, 7, 5), 'array';
ELSE
IF SUBSTRING(@value, 1, 7) = '@string'
INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id)
SELECT @name, @parent_id, stringvalue, 'string', 0
FROM @strings
WHERE string_id = SUBSTRING(@value, 8, 5);
ELSE
IF @value IN ('true', 'false')
INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id, boolvalue)
SELECT @name, @parent_id, @value, 'boolean', 0, CASE @value WHEN 'true' THEN 1 ELSE 0 END;
ELSE
IF @value = 'null'
INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id)
SELECT @name, @parent_id, @value, 'null', 0;
ELSE
IF PATINDEX('%[^0-9]%', @value collate SQL_Latin1_General_CP850_Bin) > 0
INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id)
SELECT @name, @parent_id, @value, 'real', 0;
ELSE
INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id, bigintvalue)
SELECT @name, @parent_id, @value, 'bigint', 0, CONVERT(BIGINT,@value); END /* WHILE PATINDEX */ END /* WHILE 1=1 forever until there is nothing more to do */ INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype)
SELECT '', 0, '', @parent_id - 1, @type; RETURN; END GO PRINT 'FUNCTION dbo.ParseJSON is modified.';
GO
SQL操作Json数据的更多相关文章
- js中如何操作json数据
一.要想熟练的操作json数据,就先要了解json数据的结构,json有两种结构:对象和数组. 1.对象 一个对象以“{”开始,“}”结束.每个“名称”后跟一个“:”:“‘名称/值’ 对”之间使用“, ...
- Jquery重新学习之五[操作JSON数据]
Jquery操作Json格式的数据在我们平时的项目中也经常运用:最近看Jquery权威指南中就有一章节是对这方面的整理总结:最后通过一个Asp.net结合一般处理程序ashx的实例,基本上能满足项目中 ...
- Java操作JSON数据(4,end)--Jackson操作JSON数据
Jackson是SpringBoot默认使用的JSON处理库,它可以轻松的将Java对象转换成JSON对象,同样也可以将JSON转换成Java对象.本文介绍下Jackson的基本使用方法,包括序列化和 ...
- Java操作JSON数据(3)--fastjson操作JSON数据
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean.本文介绍下fastjs ...
- Java操作JSON数据(2)--Gson操作JSON数据
Gson是Google公司发布的一个开发源码的Java库,可用于将Java对象转换为JSON字符串,也可用于将JSON字符串转换为对应的Java对象.本介绍下Gson的基本使用方法,包括序列化和反序列 ...
- Java操作JSON数据(1)--JSON-lib操作JSON数据
JSON-lib是一个java库,用于将bean.映射.集合.java数组和XML转换为JSON,或将JSON转为beans和DynaBeans.JSON-lib最后的版本是2.4,更新时间是2010 ...
- js之操作JSON数据
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...
- Android(java)学习笔记208:Android中操作JSON数据(Json和Jsonarray)
1.Json 和 Xml JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的 ...
- [转] jQuery 操作 JSON 数据
jquery下json数组的操作用法实例: jquery中操作JSON数组的情况中遍历方法用的比较多,但用添加移除这些好像就不是太多了. 试过json[i].remove(),json.remove( ...
随机推荐
- zuluCryt cli howto
1.解锁卷的命令. zuluCrypt-cli -o -d /dev/sdc1 -m blabla -e ro -f /home/keyFile zuluCrypt-cli -o -d /dev/sd ...
- Python之安装第三方扩展库
PyPI 地址:https://pypi.python.org/pypi 如果你知道你要找的库的名字,那么只需要在右上角搜索栏查找即可. 1.pip安装扩展库 (1)安装最新版本的扩展库: cmd&g ...
- Mac下默认JDK路径
2.JDK8以及JDK7安装的默认路径为:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk
- 前端技术俗语js
注:原文是英文,本文是我翻译的.有人把我翻译的内容原文照抄,放到他自己的专栏,搞得有人问我是不是我抄袭了……请支持我的劳动成果,花了两个小时翻译的,谢谢.转载请注明译者为方应杭. 嘿,我最近接到一个 ...
- Android-ActivityManager 退出整个应用
在做Android APP 过程中,有退出整个Project的功能,以下就是接受退出整个应用的操作: ActivityManager是用来管理记录每一个Activity,最后统一用来退出结束: pub ...
- Reporting Service服务SharePoint集成模式安装配置(5、安装 SQL SERVER 2012 SP1产品)
有过SQL2012 数据库安装经验的,可以跳过这一步骤直接进入第五步骤:RS外接程序的安装 数据库安装工具:SQLServer2012 SP1 Name:SQLServer2012SP1-FullS ...
- Windows store app[Part 3]:认识WinRT的异步机制
WinRT异步机制的诞生背景 当编写一个触控应用程序时,执行一个耗时函数,并通知UI更新,我们希望所有的交互过程都可以做出快速的反应.流畅的操作感变的十分重要. 在连接外部程序接口获取数据,操作本地数 ...
- winfrom 右下角弹窗(渐渐消失)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- leetcode 移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 这道题比较好想出来 /** ...
- 反射:获取Class对象的三种方式
获取Class对象的三种方式 package lianxiApril18; /** * 获取Class对象的三种方式 * 1 Object ——> getClass(); * 2 任何数据类型( ...