SQL Server: JSON without an array wrapper at lower levels

All I'm trying to get is a simple SQL statement to build

 {"status":{"code":404,"message":"Not found"},"otherthing":20}

If I asked like:

DECLARE @ReturnJSON nvarchar(max)

SET @ReturnJSON = (
    SELECT ( 
        SELECT 404 as [code]
              ,'Not found' as [message] 
               FOR JSON PATH ) as [status]
       , 20 as [otherthing]
   FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) ;

SELECT @ReturnJSON 

I get the second level under the shell of the array, for example:

{"status":[{"code":404,"message":"Not found"}],"otherthing":20}

But if I add WITHOUT_ARRAY_WRAPPER to the second level ...

DECLARE @ReturnJSON nvarchar(max)

SET @ReturnJSON = (
    SELECT ( 
        SELECT 404 as [code]
              ,'Not found' as [message] 
               FOR JSON PATH, WITHOUT_ARRAY_WRAPPER ) as [status]
       , 20 as [otherthing]
   FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) ;

SELECT @ReturnJSON 

something funny happens:

{"status":"{\"code\":404,\"message\":\"Not found\"}","otherthing":20}

I'm missing something, I know, of course, but I can’t see

+4
source share
1 answer

I think Mateno (in the comments) is right: apparently the problem is that it FOR JSONeludes your text. To prevent this unwanted escaping of internal JSON, you can wrap it with JSON_QUERY():

DECLARE @ReturnJSON nvarchar(max)
DECLARE @innerJSON nvarchar(max)

set @innerJSON =(        SELECT 404 as [code]
              ,'Not found' as [message] 
               FOR JSON PATH, WITHOUT_ARRAY_WRAPPER )

SET @ReturnJSON = (
    SELECT ( 
        JSON_QUERY(@innerJSON)
               ) as [status]
       , 20 as [otherthing]
   FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) ;

SELECT @ReturnJSON 

It is output:

{"status":{"code":404,"message":"Not found"},"otherthing":20}
+3
source

Source: https://habr.com/ru/post/1668389/


All Articles