JSON没有较低级别的数组包装器

时间:2017-01-31 12:39:19

标签: sql json sql-server tsql

我试图获得的是一个简单的SQL语句来构建:

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

如果我设为:

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 

我在数组包装器下获得第二级,如下所示:

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

但如果我在第二级添加WITHOUT_ARRAY_WRAPPER ......

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 
发生了一些有趣的事情:

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

我遗失了一些东西,我知道,当然,但是我不能看到

2 个答案:

答案 0 :(得分:8)

我认为Matheno(在评论中)是对的:显然问题是FOR JSON逃脱了你的文本。为了防止这种不必要的内部JSON转义,你可以用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 

输出:

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

答案 1 :(得分:0)

这不是您问题的确切答案,但我希望它能为您解决问题。

您可以构建不带嵌套查询的预期输出,只需使用属性名称定义层次结构即可,

DECLARE @ReturnJSON nvarchar(max)

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

SELECT @ReturnJSON