如何解决使用T-SQL的动态JSON解析
我有一个高度非结构化的JSON字符串,作为调用REST API的响应:
{
"info": "Test Json Structure","Owner": "Self-Owned","managedobjects": [{
"Name": "Device1","Class": "A"
},{
"Name": "Device2","Class_145": "Ax01","Class_11": "B","Type_125478": {
"Model": "1","Manufacturer": "External"
},"Type_SD": {
"Model": "00","Manufacturer": "Internal"
}
},{
"Name": "Device3","Class_x": "Cx11","Class_T": "C8Y","Type": {
"Model": "1x","Manufacturer": "Internal"
}
}
]
}
如何使用T-sql动态分析此对象,以便所有子元素代表表的列?更重要的是,如何处理Type
,Type_125478
,Type_SD
对象,这些对象实际上具有相同的结构(Model,Manufacturer
),但是它们的名称有些不同。另外请记住,该设备可能会发送一个以前不存在的新标识符(Type_XYZ
),但幸运的是具有相同的结构(Model,Manufacturer
)。
解决方法
您可能会使用类似的方法将整批商品分解为表格结构并继续进行处理(需要使用SQL Server v2016 +版本):
DECLARE @YourJSON NVARCHAR(MAX)=
N'{
"info": "Test Json Structure","Owner": "Self-Owned","managedObjects": [{
"Name": "Device1","Class": "A"
},{
"Name": "Device2","Class_145": "Ax01","Class_11": "B","Type_125478": {
"Model": "1","Manufacturer": "External"
},"Type_SD": {
"Model": "00","Manufacturer": "Internal"
}
},{
"Name": "Device3","Class_x": "Cx11","Class_T": "C8Y","Type": {
"Model": "1x","Manufacturer": "Internal"
}
}
]
}';
-查询
SELECT A.info,A.[Owner],C.[key] AS TagName,CASE WHEN D.Model IS NULL THEN C.[value] END AS TagValue,D.Model,D.Manufacturer
FROM OPENJSON(@YourJSON)
WITH(info NVARCHAR(MAX),[Owner] NVARCHAR(MAX),managedObjects NVARCHAR(MAX) AS JSON) A
OUTER APPLY OPENJSON(A.managedObjects) B
OUTER APPLY OPENJSON(B.[value]) C
OUTER APPLY OPENJSON(CASE WHEN ISJSON(C.[value])=1 THEN C.[value] END)
WITH (Model NVARCHAR(MAX),Manufacturer NVARCHAR(MAX))D;
-结果
+---------------------+------------+-------------+----------+-------+--------------+
| info | Owner | TagName | TagValue | Model | Manufacturer |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name | Device1 | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class | A | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name | Device2 | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_145 | Ax01 | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_11 | B | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type_125478 | | 1 | External |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type_SD | | 00 | Internal |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name | Device3 | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_x | Cx11 | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_T | C8Y | | |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type | | 1x | Internal |
+---------------------+------------+-------------+----------+-------+--------------+
提示:您可以在结果中添加B.[key]
作为对象标识符。
简而言之
- 我们使用第一个
OPENJSON
进入您的JSON。WITH
子句允许将JSON-props列为地址。我们自己将managedObejcts
作为JSON返回。 - 我们再使用
OPENJSON
来深入研究托管对象。 - 这将返回一个对象数组。我们可以将
value
传递给另一个OPENJSON
。 - 只要
value
本身可以解释为JSON,我们就会再使用OPENJSON
,这一次使用WITH
条款来获取内部属性作为列。 / li>
您可以将此结果插入表(已声明,临时,物理...)中,并继续使用此易于阅读的设置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。