【发布时间】:2021-04-01 07:03:30
【问题描述】:
您好,我一直试图从 SQL 中的 XML 插入两个表(组和字段)。但该解决方案要么无法解决我的问题,要么性能很慢,因为组和字段的数量可能达到数十万。
XML 示例:
<?xml version="1.0" encoding="utf-16"?>
<FB_Flow
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="1">
<groups>
<FB_FlowGroup counter="1125" position="2" positionparent="0" id="0">
<fields>
<FB_FlowField>
<value>TEST1</value>
<counter>111</counter>
<lineposition>1</lineposition>
</FB_FlowField>
<FB_FlowField>
<value>TEST2</value>
<counter>222</counter>
<lineposition>2</lineposition>
<groupid>0</groupid>
</FB_FlowField>
<FB_FlowField>
<value>TEST3</value>
<counter>333</counter>
<lineposition>3</lineposition>
</FB_FlowField>
</fields>
</FB_FlowGroup>
<FB_FlowGroup counter="1126" position="3" positionparent="2" id="0">
<fields>
<FB_FlowField>
<value>TEST1</value>
<counter>18</counter>
<lineposition>1</lineposition>
</FB_FlowField>
</fields>
</FB_FlowGroup>
</groups>
</FB_Flow>
第一部分工作正常(获取所有组的列表)
insert into @Groups (intGroupCounter,intGroupPosition,intGroupPositionParent)
SELECT
gcounter = Groups.value('@counter[1]', 'int'),
gposition = Groups.value('@position[1]', 'int'),
gpositionparent = Groups.value('@positionparent[1]', 'int')
FROM
@FlowXML.nodes('/FB_Flow/groups/FB_FlowGroup') AS XTbl(Groups)
第二部分大部分都失败了(获取所有具有父组位置的字段):
insert into @Fields (intGroupPosition,vFieldValue,intFieldCounter,intFieldPosition)
SELECT
gposition = XTbl.Groups.value('@position', 'int'),
fValue = XTbl2.Fields.value('value[1]', 'varchar(max)'),
fcounter = XTbl2.Fields.value('counter[1]', 'int'),
fposition = XTbl2.Fields.value('lineposition[1]', 'int')
FROM
@FlowXML.nodes('/FB_Flow/groups/FB_FlowGroup') AS XTbl(Groups)
cross APPLY
Groups.nodes('fields/FB_FlowField') AS XTbl2(Fields)
我一直通过使用光标并按位置属性选择组来解决这个问题,但性能很差。
DECLARE @GroupCounter int,
@GroupPosition int,
@GroupPositionParent int,
@GroupID int
DECLARE @Groups table
(
intGroupCounter int not null,
intGroupPosition int not null,
intGroupPositionParent int null default 0
)
insert into @Groups (intGroupCounter,intGroupPosition,intGroupPositionParent)
SELECT
gcounter = Groups.value('@counter[1]', 'int'),
gposition = Groups.value('@position[1]', 'int'),
gpositionparent = Groups.value('@positionparent[1]', 'int')
FROM
@FlowXML.nodes('/FB_Flow/groups/FB_FlowGroup') AS XTbl(Groups)
DECLARE cur cursor for
SELECT
intGroupCounter,
intGroupPosition,
intGroupPositionParent
FROM
@Groups
OPEN cur
FETCH NEXT FROM cur INTO @GroupCounter, @GroupPosition, @GroupPositionParent
WHILE @@FETCH_STATUS = 0
BEGIN
insert into FB_T_FlowGroups (FH_ID,DTC_GroupCounter,Position,PositionParent)
values (@FlowHeaderID,@GroupCounter,@GroupPosition,@GroupPositionParent)
select @GroupID = @@IDENTITY
--declare @Path varchar(max) = '/FB_Flow/groups/FB_FlowGroup[@position="sql:variable("@GroupPosition")"]/fields/FB_FlowField'
insert into FB_T_FlowGroupField (FlowGroupID,ItemValue,DTC_ItemCounter)
SELECT
@GroupID,
XTbl.Fields.value('value[1]', 'varchar(max)'),
XTbl.Fields.value('counter[1]', 'int')
FROM
@FlowXML.nodes('/FB_Flow/groups/FB_FlowGroup[@position=sql:variable("@GroupPosition")]/fields/FB_FlowField') AS XTbl(Fields)
FETCH NEXT FROM cur INTO @GroupCounter, @GroupPosition, @GroupPositionParent
END
CLOSE cur
DEALLOCATE cur
有什么想法吗?
【问题讨论】:
标签: sql-server xml tsql optimization xquery