SQL to JSON as table

Source: Internet
Author: User
Tags control characters hex to decimal

To create a method:

 /****** object:userdefinedfunction [dbo].    [Parsejson] Script DATE:2017/7/11 18:27:28 ******/set ansi_nulls ongoset quoted_identifier ongocreate 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's in this column. The document is the ultimate parent and so can get the structure from recursing from the document */OBJECT_ID int,/* E Ach list or object has an object ID. This ties any elements to a parent. Lists is treated as objects here */name NVARCHAR (+),/* The name of the object */StringValue NVARCHAR (MAX) not NU Ll,/*the string representation of the value of the element.  */ValueType VARCHAR (+) NOT NULL/* The declared type of the value represented as a string in stringvalue*/) Asbegin 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 NV Archar,--Whether it denotes an object or an array @NextCloseDelimiterChar CHAR (1),--either a '} ' or a '] ' @Conte NTS NVARCHAR (MAX),--the unparsed contents of the bracketed expression @Start INT,--index of the Start of the token th At your is parsing @end int,--Index of the end of the token that is parsing @param INT,--The parameter at the E     nd of the next Object/array token @EndOfName INT,--The index of the start of the parameter at end of Object/array token  @token NVARCHAR,--either a string or object @value NVARCHAR (MAX),--the value as a string @SequenceNo int, --The sequence numberWithin a list @name NVARCHAR,--the name as a string @parent_ID INT,--the next parent ID to allocate @lenJSO N INT,--The current length of the JSON String @characters NCHAR ($),--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 is ' escaped ' in a different, and may contain, unescaped, brackets denoting objects or lists . These is replaced in the JSON string by tokens representing the string */(string_id INT IDENTITY (1, 1), Stri Ngvalue NVARCHAR (MAX)) select--initialise the characters to convert hex to ASCII @characters = ' 0123456789abcdefghij Klmnopqrstuvwxyz ', @SequenceNo =0,--set the sequence No.  to something sensible. /* Firstly we process all strings. This is the done because [{}and] aren ' t escaped in strings, which complicates an iterative parse.  */@parent_ID = 0; While 1=1--forever until there are 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 L          OOP IF SUBSTRING (@json, @start +1, 1) = ' "' BEGIN--delimited Name SET @[email protected]+1; SET @end =patindex ('%[^\][']% ', right (@json, LEN (@json + ' | ') [email protected])        Collate sql_latin1_general_cp850_bin); End IF @end =0--no end delimiter to the 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) FRO M (select ' \ ' ' as fromstring, ' ' as ToString union ALL select ' \ \ ', ' \ ' UNION ALL Select ' \/', '/' UNION all SELECT ' \b ', CHAR () union ALL SELECT ' \f ', char (+) union ALL select ' \ n ', char (TEN) union ALL select ' \ R ', char ( UNION all select ' \ t ', CHAR (in)) substitutions SELECT @result =0, @escape =1--begin to take out a NY hex Escape codes while @escape >0 BEGIN SELECT @index =0,--find the next hex escape seq          Uence @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 be always four digits to a \x sequence BEGIN SELECT--determine its value @[email protecte                                D]+power (@index) * (CHARINDEX (SUBSTRING (@token, @[email protected], 1),                         @characters)-1), @[email protected]+1; END--and replace the hex sequence by its Unicode ValUE SELECT @token =stuff (@token, @escape, 6, NCHAR (@result)) end End--now Store the STR ing away INSERT into @Strings (stringvalue) Select @token--and replace the string with a token SELECT @J  Son=stuff (@json, @start, @end +1, ' @string ' +convert (NVARCHAR (5), @ @identity)) End-all strings is Now removed.    Now we find the first leaf. While 1=1--forever until there are nothing more to do BEGIN SELECT @[email protected]_id+1--find the first obje CT 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 @NextCloseDelimit Erchar= '} ', @type = ' object ' ELSE SELECT @NextCloseDelimiterChar = '] ', @type = ' array ' select @[email protected] WH    ILE 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-del Imiter of either type SELECT @NextOpenDelimiter =patindex ('%[{[[]% ', right (@json, @[email protected]) Collate sql_latin1_general_cp850_bin)--object IF @NextOpenDelimiter =0 break SELECT @[email protecte D][email protected] If @NextCloseDelimiter < @NextOpenDelimiter break if SUBSTRING (@json, @NextOpe Ndelimiter, 1) = ' {' SELECT @NextCloseDelimiterChar = '} ', @type = ' object ' ELSE select @NextCloseDelimiter    Char= '] ', @type = ' array ' SELECT @[email protected] END---and parse out the list or name/value pairs SELECT @contents =substring (@json, @OpenDelimiter +1, @[email protected]) SELECT @JSON =stuff (@js     On, @OpenDelimiter,           @[email protected]+1, ' @ ' [Email protected]+convert (NVARCHAR (5), @parent_ID)) while (P Atindex ('%[[email protected]+.e]% ', @contents collate sql_latin1_general_cp850_bin)) <>0 BEGIN IF @Type          = ' Object '--it is a 0-n list containing a string followed by a string, Number,boolean, or null BEGIN SELECT @SequenceNo =0, @end =charindex (': ', ' [email protected])--if There is anything, it'll be a string-          Based name. SELECT @start =patindex ('%[^[email protected]][@]% ', ' [email protected] collate sql_latin1_general_cp850            _bin)--aaaaaaaa SELECT @token =substring ("[email protected], @start +1, @[email protected]), @endofname =patindex ('%[0-9]% ', @token collate sql_latin1_general_cp850_bin), @param =right (@token, LEN (@token) [ email protected]+1) SELECT @token =left (@token, @endofname-1), @Contents =right ("[Emai L prOtected], LEN (' [email protected]+ ' | ')          [email protected])         SELECT @name =stringvalue from @strings WHERE [email protected]--fetch the name END ELSE Select @Name =null,@[email protected]+1 Select @end =charindex (', ', @contents)--a String-token, objec T-token, List-token, Number,boolean, or null IF @end =0 SELECT @end =patindex ('%[[email protected]+.e][^[ email protected]+.e]% ', @Contents + ' collate sql_latin1_general_cp850_bin) +1 SELECT @start =pa Tindex ('%[^[email protected]+.e][[email protected]+.e]% ', ' [email protected] collate SQL_Latin1_ General_cp850_bin)--select @start, @end, LEN (@contents + ' | '), @contents select @Value =rtrim (SUBSTRING (@c Ontents, @start, @[email protected]), @Contents =right (@contents + ", LEN (@contents + ' | ')      [email protected])    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, String Value, object_id, ValueType) SELECT @name, @SequenceNo, @parent_ID, SUBSTRING (@value, 7, 5), SUBST               RING (@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=subst                RING (@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 Coll Ate sql_latin1_general_cp850_bin) >0 INSERT into @hierarchy (NAME, Sequenceno, pare nt_id, StringValue, ValueType) SELECT @name, @SequenceNo, @parent_ID, @value, ' real ' ELS                    E INSERT into @hierarchy (NAME, Sequenceno, parent_id, StringValue, ValueType) Select @name, @SequenceNo, @parent_ID, @value, ' int ' If @Contents = ' Select @SequenceNo =0 END endins ERT into @hierarchy (NAME, Sequenceno, parent_id, StringValue, object_id, ValueType) SELECT '-', 1, NULL, ', @parent_id-1 , @type--Returnendgo

Execute statement:

SELECT *     

  

SQL to JSON as table

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.