Arrays T-SQL解析包含动态值数组的JSON

Arrays T-SQL解析包含动态值数组的JSON,arrays,json,tsql,Arrays,Json,Tsql,在T-SQL中,解析JSON并以动态方式处理数组似乎很清楚,我们需要使用OPENJSON表值函数来处理这样一个事实,即不知道可用的索引。如果此数组是值的简单数组: SELECT * FROM OPENJSON(N'["element1","element2","element3"]') 它按预期每行使用一个元素进行渲染;非常适合计算行数和迭代值。但是,我需要反向执行此操作并构建一个值数组。为了测试,我认为类似的方法可能会奏效: SELECT RTRIM([value]) FROM OPENJS

在T-SQL中,解析JSON并以动态方式处理数组似乎很清楚,我们需要使用OPENJSON表值函数来处理这样一个事实,即不知道可用的索引。如果此数组是值的简单数组:

SELECT *
FROM OPENJSON(N'["element1","element2","element3"]')
它按预期每行使用一个元素进行渲染;非常适合计算行数和迭代值。但是,我需要反向执行此操作并构建一个值数组。为了测试,我认为类似的方法可能会奏效:

SELECT RTRIM([value])
FROM OPENJSON(N'["element1","element2","element3"]')
ORDER BY [key] FOR JSON PATH
但我得到了一个错误:

Msg 13605,第16级,状态1,第8行列表达式和数据 没有名称或别名的源不能格式化为JSON文本 使用FOR JSON子句。向未命名的列或表添加别名

我尝试过各种形式的OPENJSON函数和JSON_查询函数,但都没有成功。我最终得出了这个解决方案:

SELECT REPLACE(REPLACE(REPLACE(CATEND,'},{"V":',','),'[{"V":','['),'}]',']')
FROM (
    SELECT (
        SELECT [value] AS V
        FROM OPENJSON(N'["element1","element2","element3"]')
        ORDER BY [key] FOR JSON PATH
    ) AS CATEND
) T

但这对我来说并不合适。我的重点和使用JSON库函数的要点是避免文本解析,并且必须包含代价高昂的REPLACE函数,这似乎是不必要的。我错过什么了吗

遗憾的是,开发人员忘记添加类似于数组提示的内容

OPENJSON可以读取裸数组,[key]是元素的位置,[value]是项,但我们无法创建具有JSON功能的数组:

有一些变通办法:

-创建模型以模拟您的问题:

DECLARE @tbl1 TABLE(ID INT IDENTITY,SomeValue VARCHAR(100));
INSERT INTO @tbl1 VALUES('Row 1'),('Row 2');

DECLARE @tbl2 TABLE(ID1 INT,SomeDetail VARCHAR(100));
INSERT INTO @tbl2 VALUES(1,'Det 1.1'),(1,'Det 1.2')
                       ,(2,'Det 2.1'),(2,'Det 2.2.'),(2,'Det 2.3');
-使用自动模式将检测连接并创建对象数组。 -这很接近,但您将无法获得未命名数组:

SELECT *
FROM @tbl1 t1
INNER JOIN @tbl2 t2 ON t1.ID=t2.ID1
FOR JSON AUTO;

/*
    {
        "ID": 1,
        "SomeValue": "Row 1",
        "t2": [
            {
                "ID1": 1,
                "SomeDetail": "Det 1.1"
            },
            {
                "ID1": 1,
                "SomeDetail": "Det 1.2"
            }
        ]
    }
*/
-使用路径模式将返回每个组合-而不是您需要的

SELECT *
FROM @tbl1 t1
INNER JOIN @tbl2 t2 ON t1.ID=t2.ID1
FOR JSON PATH;

/*
    {
        "ID": 1,
        "SomeValue": "Row 1",
        "ID1": 1,
        "SomeDetail": "Det 1.1"
    }
*/
-使用相关子查询将产生与上述自动模式相同的结果

SELECT *
      ,(
        SELECT *
        FROM @tbl2 t2 
        WHERE t2.ID1=t1.ID --<-- correlated sub-query 
        FOR JSON PATH
       ) AS Details
FROM @tbl1 t1
FOR JSON PATH;
如果你有v2017+你很幸运,因为你可以使用STRING_AGG:


目前,我们必须等待未来的版本将这一真正需要的功能带到本机上……

遗憾的是,开发人员忘记添加类似于数组提示的内容

OPENJSON可以读取裸数组,[key]是元素的位置,[value]是项,但我们无法创建具有JSON功能的数组:

有一些变通办法:

-创建模型以模拟您的问题:

DECLARE @tbl1 TABLE(ID INT IDENTITY,SomeValue VARCHAR(100));
INSERT INTO @tbl1 VALUES('Row 1'),('Row 2');

DECLARE @tbl2 TABLE(ID1 INT,SomeDetail VARCHAR(100));
INSERT INTO @tbl2 VALUES(1,'Det 1.1'),(1,'Det 1.2')
                       ,(2,'Det 2.1'),(2,'Det 2.2.'),(2,'Det 2.3');
-使用自动模式将检测连接并创建对象数组。 -这很接近,但您将无法获得未命名数组:

SELECT *
FROM @tbl1 t1
INNER JOIN @tbl2 t2 ON t1.ID=t2.ID1
FOR JSON AUTO;

/*
    {
        "ID": 1,
        "SomeValue": "Row 1",
        "t2": [
            {
                "ID1": 1,
                "SomeDetail": "Det 1.1"
            },
            {
                "ID1": 1,
                "SomeDetail": "Det 1.2"
            }
        ]
    }
*/
-使用路径模式将返回每个组合-而不是您需要的

SELECT *
FROM @tbl1 t1
INNER JOIN @tbl2 t2 ON t1.ID=t2.ID1
FOR JSON PATH;

/*
    {
        "ID": 1,
        "SomeValue": "Row 1",
        "ID1": 1,
        "SomeDetail": "Det 1.1"
    }
*/
-使用相关子查询将产生与上述自动模式相同的结果

SELECT *
      ,(
        SELECT *
        FROM @tbl2 t2 
        WHERE t2.ID1=t1.ID --<-- correlated sub-query 
        FOR JSON PATH
       ) AS Details
FROM @tbl1 t1
FOR JSON PATH;
如果你有v2017+你很幸运,因为你可以使用STRING_AGG:

目前,我们必须等待未来的版本将这个真正需要的功能带到本地