Arrays T-SQL解析包含动态值数组的JSON
在T-SQL中,解析JSON并以动态方式处理数组似乎很清楚,我们需要使用OPENJSON表值函数来处理这样一个事实,即不知道可用的索引。如果此数组是值的简单数组: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
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:
目前,我们必须等待未来的版本将这个真正需要的功能带到本地