将自定义 SELECT 结果转换为 JSON

Convert custom SELECT result into JSON

我遗漏了一些东西,似乎找不到适合这种情况的任何东西。我想将自定义 SELECT 查询输出到 VARIABLE 作为 JSON.

鉴于以下基本 table 和脚本,我可以轻松地将 SELECT 语句的结果从 table 转换为 JSON 变量:

DECLARE @Table TABLE
(
    [VALUE] nvarchar(100) Null
);

INSERT INTO @Table
SELECT N'Value 1' UNION ALL
SELECT N'Value 2' UNION ALL
SELECT N'Value 3';

DECLARE @JsonValue nvarchar(max);
SELECT @JsonValue =
(
    SELECT * 
    FROM @Table
    FOR JSON PATH
    , INCLUDE_NULL_VALUES
);
SELECT @JsonValue;

这愉快地输出 JSON:

[
    { "VALUE": "Value 1" },
    { "VALUE": "Value 2" },
    { "VALUE": "Value 3" }
]

现在,如果我想输出自定义查询:

DECLARE @JsonValue nvarchar(max);
SELECT @JsonValue =
(
    SELECT N'Value 1' AS [VALUE] UNION ALL
    SELECT N'Value 2' UNION ALL
    SELECT N'Value 3'
    FOR JSON PATH
    , INCLUDE_NULL_VALUES
);
SELECT @JsonValue;

我得到: The FOR XML and FOR JSON clauses are invalid in views, inline functions, derived tables, and subqueries when they contain a set operator. To work around, wrap the SELECT containing a set operator using derived table or common table expression or view and apply FOR XML or FOR JSON on top of it.

运行只是查询的一部分:

SELECT N'Value 1' AS [VALUE] UNION ALL
SELECT N'Value 2' UNION ALL
SELECT N'Value 3'
FOR JSON PATH
, INCLUDE_NULL_VALUES

结果 JSON

[
    { "VALUE": "Value 1" },
    { "VALUE": "Value 2" },
    { "VALUE": "Value 3" }
]

我尝试了一些不同的方法,例如 JSON_QUERY,等等,但都失败了。我可以使用 CTE,但这感觉太过分了。我已经研究了文档,但我似乎无法理解我的不足之处,所以我希望有人有洞察力为我指明正确的方向。

不要使用一堆 UNION ALL 查询,而是使用 VALUES:

DECLARE @JsonValue nvarchar(max);
SELECT @JsonValue =
(
    SELECT V.Value
    FROM (VALUES(N'Value 1'),(N'Value 2'),(N'Value 3'))V([Value])
    FOR JSON PATH , INCLUDE_NULL_VALUES
);
SELECT @JsonValue;

或者,如果您必须使用 UNION ALL,则合并子查询中的值,然后在其外部使用 FOR JSON PATH

DECLARE @JsonValue nvarchar(max);
SET @JsonValue = (SELECT [Value]
                  FROM (SELECT N'Value 1' AS [VALUE] UNION ALL
                        SELECT N'Value 2' UNION ALL
                        SELECT N'Value 3') U
                  FOR JSON PATH, INCLUDE_NULL_VALUES);
SELECT @JsonValue;