如何解决T-SQL:交叉应用;订单项上的迭代次数过多
之所以会得到重复的行,是因为您正在对中的每一行的整个XML使用交叉应用GenericSubHeader
。你必须想出一个办法来映射所产生ID
的GenericHeader
和所产生subid
的GenericSubHeader
对XML的相关部分。
如果您使用的是sql Server 2008或更高版本,则可以与输出合并以创建一个表变量,该表变量包含生成的ID和所属的xml子节点。
declare @GH table
(
id int,
sub xml
);
merge scratch.GenericHeader as T
using
(
select T.c.value('col1[1]','varchar(10)'),
T.c.value('col2[1]','varchar(10)'),
T.c.query('SubHeaders')
from @MetroXML.nodes('/Header') T(c)
) as S(col1, col2, sub)
on 0 = 1
when not matched then
insert (col1, col2) values(S.col1, S.col2)
output inserted.id, S.sub into @GH;
declare @GSH table
(
id int,
subid int,
det xml
);
merge scratch.GenericSubHeader as T
using
(
select h.id,
n.x.value('col1[1]','varchar(10)'),
n.x.value('col2[1]','varchar(10)'),
n.x.query('Details')
from @GH as h
cross apply h.sub.nodes('/SubHeaders/SubHeader') n(x)
) as S(id, col1, col2, det)
on 0 = 1
when not matched then
insert (id, col1, col2) values (S.id, S.col1, S.col2)
output inserted.id, inserted.subid, S.det into @GSH;
insert into scratch.GenericDetail(id, subid, col1, col2)
select s.id,
s.subid,
n.x.value('col1[1]','varchar(10)') AS 'col1',
n.x.value('col2[1]','varchar(10)') AS 'col2'
from @GSH as s
cross apply s.det.nodes('/Details/Detail') as n(x);
解决方法
在分解了一些严重的Xml之后,我几乎满足了我的需求-但是查看结果后,我发现在解析的一部分中,我无法轻松地解决这种遍历所有行细节的模式每个子标题-
因此,我没有为所有订单项写出总计3条记录,而是为每个子项目写出了三个订单项-
假设我有两个。我总共有6个!:-(我在下面的代码中将模式提炼为通用的标头/子标头/详细信息关系模型。
DECLARE @MetroXML xml
SET @MetroXML =
'<Header>
<col1>Conoco</col1>
<col2>ORD-1111</col2>
<SubHeaders>
<SubHeader>
<col1>Dallas</col1>
<col2>BOL-2213</col2>
<Details>
<Detail>
<col1>Diesel</col1>
<col2>7600.00</col2>
</Detail>
</Details>
</SubHeader>
</SubHeaders>
<SubHeaders>
<SubHeader>
<col1>Fort Worth</col1>
<col2>BOL-2216</col2>
<Details>
<Detail>
<col1>Ethanol</col1>
<col2>1852.00</col2>
</Detail>
<Detail>
<col1>Unleaded</col1>
<col2>900.00</col2>
</Detail>
</Details>
</SubHeader>
</SubHeaders>
</Header>';
INSERT INTO [scratch].GenericHeader
SELECT T.c.value('col1[1]','varchar(10)') AS 'col1',T.c.value('col2[1]','varchar(10)') AS 'col2'
FROM @MetroXML.nodes('/Header') T(c);
INSERT [scratch].GenericSubHeader
(id,col1,col2)
SELECT
h.id,n.x.value('col1[1]',n.x.value('col2[1]','varchar(10)') AS 'col2'
FROM [scratch].GenericHeader h
CROSS APPLY @MetroXML.nodes('/Header/SubHeaders/SubHeader') n(x);
INSERT [scratch].GenericDetail
(id,subid,col2)
SELECT
s.id,s.subid,'varchar(10)') AS 'col2'
FROM [scratch].GenericSubHeader s
CROSS APPLY @MetroXML.nodes('/Header/SubHeaders/SubHeader/Details/Detail') as n(x);
select * from [scratch].GenericHeader
where id = 24;
select * from [scratch].GenericSubHeader
where id = 24;
select * from [scratch].GenericDetail
where id = 24;
注意:id,subid,detid被定义为INT IDENTITY(1,1)结果
我得到的是:
id|subid|detid|col1 |col2
--------------------------------
24|44 |22 |Diesel |7600.00
24|44 |23 |Ethanol |1852.00
24|44 |24 |Unleaded |900.00
24|48 |25 |Diesel |7600.00
24|48 |26 |Ethanol |1852.00
24|48 |27 |Unleaded |900.00
我想要得到什么:
id|subid|detid|col1 |col2
--------------------------------
24|44 |22 |Diesel |7600.00
24|48 |23 |Ethanol |1852.00
24|48 |24 |Unleaded |900.00
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。