利用下列表值函数 将数据库表 转换为JSon字符串

利用下列表值函数  将数据库表 转换为JSon字符串
 

/****** Object: UserDefinedFunction [dbo].[parseJSON] Script Date: 07/16/2020 14:40:06 ******/

SET ANSI_NULLS ON

GO

 

SET QUOTED_IDENTIFIER ON

GO

 

CREATE FUNCTION [dbo].[parseJSON] ( @JSON NVARCHAR(MAX) )

RETURNS @hierarchy TABLE

(

element_id INT IDENTITY(1, 1)

NOT NULL , /* internal surrogate primary key gives the order of parsing and the list order */

sequenceNo [INT] NULL , /* the place in the sequence for the element */

parent_ID INT ,/* 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 */

Object_ID INT ,/* each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */

NAME NVARCHAR(2000) ,/* the name of the object */

StringValue NVARCHAR(MAX) NOT NULL ,/*the string representation of the value of the element. */

ValueType VARCHAR(10) NOT NULL /* the declared type of the value represented as a string in StringValue*/

)

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(200) ,--either a string or object

@value NVARCHAR(MAX) , -- the value as a string

@SequenceNo INT , -- the sequence number within a list

@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(36) ,--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

DECLARE @Strings TABLE /* 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 */

(

String_ID INT IDENTITY(1, 1) ,

StringValue NVARCHAR(MAX)

);

SELECT--initialise the characters to convert hex to ascii

@characters = '0123456789abcdefghijklmnopqrstuvwxyz' ,

@SequenceNo = 0 , --set the sequence no. to something sensible.

/* firstly we process all strings. This is done because [{} and ] aren't escaped in strings, which complicates an iterative parse. */

@parent_ID = 0;

WHILE 1 = 1 --forever until there is nothing more to do

BEGIN

SELECT @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));

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, FromString, ToString)

FROM ( SELECT '\"' AS FromString ,

'"' AS ToString

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;

SELECT @result = 0 ,

@Escape = 1;

--Begin to take out any hex escape codes

WHILE @Escape > 0

BEGIN

SELECT @index = 0 ,

--find the next hex escape sequence

@Escape = PATINDEX('%\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%',

@token);

IF @Escape > 0 --if there is one

BEGIN

WHILE @index < 4 --there are always four digits to a \x sequence

BEGIN

SELECT --determine its value

@result = @result + POWER(16,

@index)

* ( CHARINDEX(SUBSTRING(@token,

@Escape + 2 + 3

- @index, 1),

@characters) - 1 ) ,

@index = @index + 1;

END;

-- and replace the hex sequence by its unicode value

SELECT @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

SELECT @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

SELECT @parent_ID = @parent_ID + 1;

--find the first object or list by looking for the open bracket

SELECT @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';

SELECT @OpenDelimiter = @FirstObject;

WHILE 1 = 1 --find the innermost object or list...

BEGIN

SELECT @lenJSON = LEN(@JSON + '|') - 1;

--find the matching close-delimiter proceeding after the open-delimiter

SELECT @NextCloseDelimiter = CHARINDEX(@NextCloseDelimiterChar,

@JSON,

@OpenDelimiter

+ 1);

--is there an intervening open-delimiter of either type

SELECT @NextOpenDelimiter = PATINDEX('%[{[[]%',

RIGHT(@JSON,

@lenJSON

- @OpenDelimiter)COLLATE SQL_Latin1_General_CP850_BIN);--object

IF @NextOpenDelimiter = 0

BREAK;

SELECT @NextOpenDelimiter = @NextOpenDelimiter

+ @OpenDelimiter;

IF @NextCloseDelimiter < @NextOpenDelimiter

BREAK;

IF SUBSTRING(@JSON, @NextOpenDelimiter, 1) = '{'

SELECT @NextCloseDelimiterChar = '}' ,

@Type = 'object';

ELSE

SELECT @NextCloseDelimiterChar = ']' ,

@Type = 'array';

SELECT @OpenDelimiter = @NextOpenDelimiter;

END;

---and parse out the list or name/value pairs

SELECT @Contents = SUBSTRING(@JSON, @OpenDelimiter + 1,

@NextCloseDelimiter

- @OpenDelimiter - 1);

SELECT @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

IF @Type = 'Object' --it will be a 0-n list containing a string followed by a string, number,boolean, or null

BEGIN

SELECT @SequenceNo = 0 ,

@end = CHARINDEX(':', ' ' + @Contents);--if there is anything, it will be a string-based name.

SELECT @Start = PATINDEX('%[^A-Za-z@][@]%',

' ' + @Contents);--AAAAAAAA

SELECT @token = SUBSTRING(' ' + @Contents,

@Start + 1,

@end - @Start - 1) ,

@EndOfName = PATINDEX('%[0-9]%',

@token COLLATE SQL_Latin1_General_CP850_BIN) ,

@param = RIGHT(@token,

LEN(@token)

- @EndOfName + 1);

SELECT @token = LEFT(@token, @EndOfName - 1) ,

@Contents = RIGHT(' ' + @Contents,

LEN(' ' + @Contents

+ '|') - @end

- 1);

SELECT @name = StringValue

FROM @Strings

WHERE String_ID = @param; --fetch the name

END;

ELSE

SELECT @name = NULL ,

@SequenceNo = @SequenceNo + 1;

SELECT @end = CHARINDEX(',', @Contents);-- a string-token, object-token, list-token, number,boolean, or null

IF @end = 0

SELECT @end = PATINDEX('%[A-Za-z0-9@+.e][^A-Za-z0-9@+.e]%',

@Contents + ' ') + 1;

SELECT @Start = PATINDEX('%[^A-Za-z0-9@+.e][A-Za-z0-9@+.e]%',

' ' + @Contents);

--select @start,@end, LEN(@contents+'|'), @contents

SELECT @value = RTRIM(SUBSTRING(@Contents, @Start,

@end - @Start)) ,

@Contents = RIGHT(@Contents + ' ',

LEN(@Contents + '|') - @end);

IF SUBSTRING(@value, 1, 7) = '@object'

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

Object_ID ,

ValueType

)

SELECT @name ,

@SequenceNo ,

@parent_ID ,

SUBSTRING(@value, 8, 5) ,

SUBSTRING(@value, 8, 5) ,

'object';

ELSE

IF SUBSTRING(@value, 1, 6) = '@array'

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

Object_ID ,

ValueType

)

SELECT @name ,

@SequenceNo ,

@parent_ID ,

SUBSTRING(@value, 7, 5) ,

SUBSTRING(@value, 7, 5) ,

'array';

ELSE

IF SUBSTRING(@value, 1, 7) = '@string'

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

ValueType

)

SELECT @name ,

@SequenceNo ,

@parent_ID ,

StringValue ,

'string'

FROM @Strings

WHERE String_ID = SUBSTRING(@value,

8, 5);

ELSE

IF @value IN ( 'true', 'false' )

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

ValueType

)

SELECT @name ,

@SequenceNo ,

@parent_ID ,

@value ,

'boolean';

ELSE

IF @value = 'null'

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

ValueType

)

SELECT @name ,

@SequenceNo ,

@parent_ID ,

@value ,

'null';

ELSE

IF PATINDEX('%[^0-9]%',

@value COLLATE SQL_Latin1_General_CP850_BIN) > 0

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

ValueType

)

SELECT

@name ,

@SequenceNo ,

@parent_ID ,

@value ,

'real';

ELSE

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

ValueType

)

SELECT

@name ,

@SequenceNo ,

@parent_ID ,

@value ,

'int';

IF @Contents = ' '

SELECT @SequenceNo = 0;

END;

END;

INSERT INTO @hierarchy

( NAME ,

sequenceNo ,

parent_ID ,

StringValue ,

Object_ID ,

ValueType

)

SELECT '-' ,

1 ,

NULL ,

'' ,

@parent_ID - 1 ,

@Type;

--

RETURN;

END;

GO

 

 

 

测试实例————————————————————————————————————————

select * from dbo.parseJSON('{"code":0,"msg":"ok","val":{"18292":[[["36.70522527","119.1653236"],["36.70651567","119.1716883"],["36.70728201","119.1759104"],["36.70839932","119.1815923"],["36.7089961","119.1849295"],["36.70974856","119.1888686"],["36.70982454","119.1892683"],["36.70993309","119.1898791"],["36.70965822","119.1899061"],["36.7080814","119.1899106"],["36.7062369","119.189951"],["36.70411025","119.18996"],["36.70184972","119.190014"],["36.69905021","119.1900454"],["36.69748401","119.189996"],["36.69533179","119.1898164"],["36.69433344","119.1897176"],["36.69332784","119.1896367"],["36.69220646","119.189475"],["36.68985515","119.1891427"],["36.68848051","119.1890439"],["36.68756166","119.189008"],["36.68672961","119.1888463"],["36.6867367","119.1861065"],["36.68678004","119.1826481"],["36.68695408","119.1741231"],["36.68697634","119.1691553"],["36.68706346","119.1666939"],["36.68703458","119.1661998"],["36.68770745","119.1661548"],["36.68827903","119.1661369"],["36.69017461","119.1658943"],["36.69199056","119.1657146"],["36.69435629","119.1654091"],["36.6959334","119.1652564"],["36.69652662","119.1651665"],["36.7001871","119.1647891"],["36.70193048","119.1645645"],["36.70409336","119.1644028"],["36.70511328","119.1643578"],["36.70522527","119.1653236"]]]}} ')

 

select ROW_NUMBER() over(order by a.parent_ID asc) as ID,

a.parent_ID,MAX(a.[1]) as 'Lat',MAX(a.[2]) as 'Lng'

from (select * from dbo.parseJSON('{"code":0,"msg":"ok","val":{"18292":[[["36.70522527","119.1653236"],["36.70651567","119.1716883"],["36.70728201","119.1759104"],["36.70839932","119.1815923"],["36.7089961","119.1849295"],["36.70974856","119.1888686"],["36.70982454","119.1892683"],["36.70993309","119.1898791"],["36.70965822","119.1899061"],["36.7080814","119.1899106"],["36.7062369","119.189951"],["36.70411025","119.18996"],["36.70184972","119.190014"],["36.69905021","119.1900454"],["36.69748401","119.189996"],["36.69533179","119.1898164"],["36.69433344","119.1897176"],["36.69332784","119.1896367"],["36.69220646","119.189475"],["36.68985515","119.1891427"],["36.68848051","119.1890439"],["36.68756166","119.189008"],["36.68672961","119.1888463"],["36.6867367","119.1861065"],["36.68678004","119.1826481"],["36.68695408","119.1741231"],["36.68697634","119.1691553"],["36.68706346","119.1666939"],["36.68703458","119.1661998"],["36.68770745","119.1661548"],["36.68827903","119.1661369"],["36.69017461","119.1658943"],["36.69199056","119.1657146"],["36.69435629","119.1654091"],["36.6959334","119.1652564"],["36.69652662","119.1651665"],["36.7001871","119.1647891"],["36.70193048","119.1645645"],["36.70409336","119.1644028"],["36.70511328","119.1643578"],["36.70522527","119.1653236"]]]}} ') a

where valueType='string' and NAME is null) json

pivot(max(StringValue) for sequenceNo in([1],[2]))a

group by a.parent_ID

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值