0

I've had created the function ParseJson below :

    create function ParseJson(
    @json nvarchar(max))
returns @tempTable table (topKey nvarchar(max), [Key] nvarchar(max), [Value] nvarchar(max))
as
begin

    insert 
        @tempTable
    select 
        x.[key] topKey
        , y.[key] 
        , y.[value] 
    from openjson(@json) x
    cross apply openjson(x.[value]) y

    return

end

-- execute
select * from ParseJson(@json)

I defined a variable @json which is not an array string :

set @json = 
N'{
  "Chapter":
  {
      "Section":"1.1"
      , "Title":"Hello world."
  }
}'

Then I execute the query I will get the result :

result_single

If I reset the variable @json which is an array string :

declare @json nvarchar(max)
set @json = 
N'{
  "Chapter":[
        {
            "Section":"1.1"
            , "Title":"Hello world."
        }
        ,
        {
            "Section":"1.2"
            , "Title":"Be happy."
        }       
    ]
}'

Then I execute the query I will get the result : result_array

I hope I can get the result below :

result

I don't know the result that I expectation is reasonable?

How can I adjust the function to meet the expectation?

3

1 Answer 1

1

If I understand your question correctly, next statement is one possible approach to get your results. It's an example that shows how to get array keys and values (I've added additional Something key). What you need is one additional CROSS APPLY.

DECLARE @json nvarchar(max)
SET @json = 
N'{
  "Chapter":[
        {
            "Section":"1.1", 
            "Title":"Hello world.",
            "Something":"Something value"
        }
        ,
        {
            "Section":"1.2", 
            "Title":"Be happy."
        }       
    ]
}'

SELECT 
   x.[key] topKey, 
   z.[key],
   z.[value]
FROM OPENJSON(@json) x
CROSS APPLY (SELECT * FROM OPENJSON(x.[value])) y
CROSS APPLY (SELECT * FROM OPENJSON(y.[value])) z

Output:

topKey  key         value
Chapter Section     1.1
Chapter Title       Hello world.
Chapter Something   Something value
Chapter Section     1.2
Chapter Title       Be happy.

Update:

If your JSON has different types of nested objects, approach will be different:

DECLARE @json nvarchar(max)
set @json = N'{ 
   "Chapter": [ 
       {
       "Section":"1.1", 
       "Title":"Hello world.", 
       "Something":"Something value"
       }, 
       {
       "Section":"1.2", 
       "Title":"Be happy." 
       }
   ], 
   "Author": { "name":"Annie" , "sex":"Female" } 
}'

SELECT 
   x.[key] topKey,
   z.[key] [Key],
   z.[value] AS [Value]
FROM OPENJSON(@json) x
CROSS APPLY (SELECT * FROM OPENJSON(x.[value])) y
CROSS APPLY (SELECT * FROM OPENJSON(y.[value])) z
WHERE y.[type] = 5
UNION ALL
SELECT 
   x.[key] topKey,
   y.[key] [Key],
   y.[value] AS [Value]
FROM OPENJSON(@json) x
CROSS APPLY (SELECT * FROM OPENJSON(x.[value])) y
WHERE y.[type] <> 5

Output:

topKey  Key         Value
Chapter Section     1.1
Chapter Title       Hello world.
Chapter Something   Something value
Chapter Section     1.2
Chapter Title       Be happy.
Author  name        Annie
Author  sex         Female
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! But if I set @json = set @json = N'{ "Chapter":[ { "Section":"1.1", "Title":"Hello world.", "Something":"Something value" } , { "Section":"1.2", "Title":"Be happy." } ] , "Author":{ "name":"Annie" , "sex":"Female" } }' I will get the error message : The JSON text format is incorrect. Unexpected character 'A' was found at position 0.
@Annie @Annie yes, because you have JSON array and JSON text for Chapter and Author. If this is your case, approach must be different for Chapter and Author. Check updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.