【发布时间】:2018-07-06 06:56:19
【问题描述】:
我一直在阅读尽可能多的相同问题的问题和答案,但我想我的问题需要更多创造性的方法。
所以我这里有一个 JSON 字符串:
declare @json nvarchar(max) =
'{
"propertyObjects": [{
"propertyID": 1
, "title": "foo"
, "class": ""
, "typeid": 150
, "value": "bar"
, "children": [{}]
}, {
"propertyID": 2
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{}]
}, {
"propertyID": 3
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{
"propertyID": 4
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{}]
}, {
"propertyID": 5
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{}]
}, {
"propertyID": 6
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{
"propertyID": 7
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{
"propertyID": 8
, "title": "foo"
, "class": ""
, "typeid": 128
, "value": "bar"
, "children": [{}]
}]
}]
}]
}]
}'
乍一看很疯狂,但这样想:
有一个名为 propertyObjects 的数组,其中包含父子结构中的多个对象。
在每个级别中,只有一个对象可以是父对象。如您所见,对象 3 里面有孩子。
我想要在表格中列出这些对象,同时为每个对象指定一个 parentID,因此对象 4 的父对象 ID 为 3,对象 3 本身的父对象为 0,因为它基本上位于顶层。
到目前为止,我尝试了一些方法,如 Common Table Expression 来进行递归调用,但我失败了:
;with cte
as
(
-- anchor member definition
select p.propertyID
, 0 as parentID
, p.title
, p.typeid
, p.[value]
, p.children
from openjson(@json, '$.propertyObjects')
with (
propertyID int
, title nvarchar(100)
, typeid int
, [value] nvarchar(1000)
, children nvarchar(max) as JSON
) as p
UNION ALL
-- recursive member definition
select 0 as propertyID
, 0 as parentID
, '' as title
, 0 typeid
, '' as [value]
, '' as children
/** child should be bound to parent **/
)
select * from cte
这就是我失败的地方,我不知道如何让它通过孩子递归查找对象。另外,我不知道如何指定每个孩子的 parentID!
propertyID parentID title typeid value children
----------------------------------------------------------------------------
1 0 foo 150 bar [{}]
2 0 foo 128 bar [{}]
3 0 foo 128 bar [{ "propertyID" : 4 ...
0 0 0
我也尝试过使用交叉应用:
select *
from
openjson(@json, '$.propertyObjects')
with (
propertyID int
, title nvarchar(100)
, typeid int
, [value] nvarchar(1000)
, children nvarchar(max) as JSON
) as p
cross apply
openjson(p.children)
with (
propertyID int
, title nvarchar(100)
, typeid int
, [value] nvarchar(1000)
, children nvarchar(max) as JSON
) as r
但不是机会,我不知道这些孩子在JSON字符串中会走多远。此外,交叉应用的结果将追加列而不是行,这会导致结果中出现巨大的表格,在这种方法中我什至不能考虑指定 parentID。
这完全是失败的,知道如何让所有孩子排成一排吗?
所需的表
propertyID parentID title typeid value
--------------------------------------------------
1 0 foo 150 bar
2 0 foo 128 bar
3 0 foo 128 bar
4 3 foo 128 bar
5 3 foo 128 bar
6 3 foo 128 bar
7 6 foo 128 bar
8 7 foo 128 bar
【问题讨论】:
-
我不确定,但您是否尝试从 JSON 文件导入数据?如果是这样,您可能想探索其他选项,例如使用 PowerShell。我猜你已经读过这个页面:docs.microsoft.com/en-us/sql/relational-databases/json/…,但为了确定,我在这里提到它。
-
ksauter 感谢您的提醒,是的,我已经阅读了所有页面,但是阅读此链接使我想起了使用与我的问题无关的内存优化表,但它会帮助我使用答案一种更优化的方式。答案将比仅使用内置函数复杂得多
-
必须是存储过程吗?是否可以选择使用 SSIS?
-
SSIS 对我来说不是一个选项,但是可以使用存储过程,任何解决这个问题的方法
标签: sql json sql-server recursion sql-server-2016