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

pGr*_*nd2 8 sql t-sql sql-server json

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

 {"status":{"code":404,"message":"Not found"},"otherthing":20}
Run Code Online (Sandbox Code Playgroud)

如果我设置为:

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 
Run Code Online (Sandbox Code Playgroud)

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

{"status":[{"code":404,"message":"Not found"}],"otherthing":20}
Run Code Online (Sandbox Code Playgroud)

但如果我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 
Run Code Online (Sandbox Code Playgroud)

有趣的事情发生:

{"status":"{\"code\":404,\"message\":\"Not found\"}","otherthing":20}
Run Code Online (Sandbox Code Playgroud)

我知道,我确实错过了一些东西,但我无法看到

And*_*rea 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 
Run Code Online (Sandbox Code Playgroud)

这输出:

{"status":{"code":404,"message":"Not found"},"otherthing":20}
Run Code Online (Sandbox Code Playgroud)

  • 相关阅读[此处](https://dba.stackexchange.com/a/148399/142517)和[此处](https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/12/21/without_array_wrapper-new -important-change-in-for-json /)。在第二个链接中:“注意一件重要的事– WITHOUT_ARRAY_WRAPPER将不会生成有效的JSON文本。如果尝试将FOR JSON WITHOUT_ARRAY_WRAPPER用作列表达式,它将被视为纯文本...” (2认同)
  • 只要只有一行, WITHOUT_ARRAY_WRAPPER 确实会生成有效的 JSON。 (2认同)

Uri*_*iil 5

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

您可以在没有嵌套查询的情况下构建预期输出,只需使用属性名称定义层次结构,如下所示:

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
Run Code Online (Sandbox Code Playgroud)