将自定义SELECT结果转换为JSON

问题描述

我丢失了一些东西,似乎找不到适合这种情况的东西。我想将自定义SELECT查询输出VARIABLEJSON

基于以下基本表和脚本,我可以轻松地将SELECT语句的结果从表转换为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 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;