将多个 SELECT 语句转换为单个 JSON

Sto*_*orm 2 t-sql sql-server json sql-server-2016

我确信这必须在某个地方得到回答,但对于我的生活,无论我如何更改搜索词组,我似乎都找不到任何东西。

我需要从两个完全独立的表中选择数据并将信息导出到 JSON。在这种情况下,它们在每个表中都是 1 条记录。

如果我一次只选择 1 个并导出到 JSON,它们是 1 个记录,但是当我在 SQL 中加入两个单个记录然后导出到 JSON 时,它们是 1 个记录数组。

仅 1 条记录 SQL 输入:

DECLARE @Json nvarchar(max) = 
(   
    SELECT 'Data1' AS [Data1], 'Data2' AS [Data2]

    FOR JSON PATH
    , INCLUDE_NULL_VALUES
    , WITHOUT_ARRAY_WRAPPER
);

SELECT @Json;
GO
Run Code Online (Sandbox Code Playgroud)

只有 1 条记录 JSON 输出(注意没有数组):

{
  "Data1": "Data1",
  "Data2": "Data2"
}
Run Code Online (Sandbox Code Playgroud)

2 记录 SQL 输入:

DECLARE @Json nvarchar(max) = 
(   
    SELECT
    (
        SELECT 'Data1' AS [Data1], 'Data2' AS [Data2]

        FOR JSON PATH
        , INCLUDE_NULL_VALUES
    ) AS [Part1]
    ,
    (
        SELECT 'Text1' AS [Text1], 'Text2' AS [Text2]

        FOR JSON PATH
        , INCLUDE_NULL_VALUES
    ) AS [Part2]

    FOR JSON PATH
    , WITHOUT_ARRAY_WRAPPER
);

SELECT @Json;
GO
Run Code Online (Sandbox Code Playgroud)

2 条记录 JSON 输出(注意包含数组):

{
  "Part1": [
    {
      "Data1": "Data1",
      "Data2": "Data2"
    }
  ],
  "Part2": [
    {
      "Text1": "Text1",
      "Text2": "Text2"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我“认为” WITHOUT_ARRAY_WRAPPER 是添加的正确属性,它将解决这个问题,但是一旦我添加它,我就会将整个记录作为一个字符串:

{
  "Part1": "{\"Data1\":\"Data1\",\"Data2\":\"Data2\"}",
  "Part2": "{\"Text1\":\"Text1\",\"Text2\":\"Text2\"}"
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用文本操作方法来使其工作,但我希望有一个干净的 SQL > JSON 语句。

我目前正在工作,SQL Server 2016但如有必要,我可以得到一个20172019服务器。不确定以后的 SQL 是否能更好地处理这个问题,或者只是我的查询需要优化。

编辑:我想要的输出是:

{
  "Part1": {
      "Data1": "Data1",
      "Data2": "Data2"
    },
  "Part2": {
      "Text1": "Text1",
      "Text2": "Text2"
    }
}
Run Code Online (Sandbox Code Playgroud)

Zoh*_*led 5

根据FOR JSON PATH的公认答案如何在 MSDN 上的 SQL Server 论坛上不使用转义字符

FOR JSON 将转义任何文本,除非它是由某些 JSON 函数/查询生成的 JSON 结果。在您的示例中,FOR JSON 无法知道您是否真的想要原始 JSON,或者您只是发送一些看起来像 JSON 的自由文本。

使用 FOR JSON(除非它具有 WITHOUT_ARRAY_WRAPPER 选项)或 JSON_QUERY 生成正确定义的 JSON。如果你用 JSON_QUERY 包装你的 JSON 文字,它不会被转义。

这个答案让我尝试以下代码:

DECLARE @Json nvarchar(max) = 
(
    SELECT
     JSON_QUERY((
        SELECT 'Data1' AS [Data1], 'Data2' AS [Data2]

        FOR JSON PATH
        , INCLUDE_NULL_VALUES
        , WITHOUT_ARRAY_WRAPPER
    )) AS [Part1]
    ,
    JSON_QUERY((
        SELECT 'Text1' AS [Text1], 'Text2' AS [Text2]

        FOR JSON PATH
        , INCLUDE_NULL_VALUES
        , WITHOUT_ARRAY_WRAPPER
    )) AS [Part2]

    FOR JSON PATH
    , WITHOUT_ARRAY_WRAPPER
);

SELECT @Json;
Run Code Online (Sandbox Code Playgroud)

事实证明 - 这就像一个魅力。结果:

{
    "Part1": {
        "Data1": "Data1",
        "Data2": "Data2"
    },
    "Part2": {
        "Text1": "Text1",
        "Text2": "Text2"
    }
}
Run Code Online (Sandbox Code Playgroud)

DB<>Fiddle


更新 看看我在官方文档中发现了什么:

为避免自动转义,请使用 JSON_QUERY 函数提供 newValue。JSON_MODIFY 知道 JSON_MODIFY 返回的值是格式正确的 JSON,因此它不会对值进行转义。