提问人:Paul Cauchon 提问时间:10/26/2017 最后编辑:Paul Cauchon 更新时间:10/27/2017 访问量:770
FOR XML EXPLICIT 中的 ORDER BY 子句
ORDER BY Clause in FOR XML EXPLICIT
问:
我有一个相当大的查询(十几个表中有 25 个标签;~1500 行),需要使用 FOR XML EXPLICIT 将其格式化为 XML。不幸的是,此文件的使用者要求使用 CDATA 标记,否则我将使用 FOR XML PATH。
这就是我要找的:
<elem elem_att1="..." elem_att2="1" elem_att3="...">
<a>...</a>
<b>...</b>
<c>...</c>
<d>...</d>
<e>
<e1 e1_att1="..." e1_att2="1">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
<e1 e1_att1="..." e1_att2="2">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
<e1 e1_att1="..." e1_att2="3">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
</e>
<f>
<f1 f1_att1="..." f1_att2="..." />
<f2 f2_att1="..." f2_att2="..." />
<f3 f3_att1="..." f3_att2="..." />
</f>
</elem>
假设在查询中正确定义了以下标记和父映射:
Tag | Parent
elem 2 | 1
a 3 | 2
b 4 | 2
c 5 | 2
d 6 | 2
e 7 | 2
e1 8 | 7
e11 9 | 8
e12 10 | 8
e13 11 | 8
f 12 | 2
f1 13 | 12
f2 14 | 12
f3 15 | 12
我已经完成了大约 90% 的查询,但遇到了与通用表中标签顺序相关的问题。我希望看到从查询返回的表的前两列的以下输出:
Tag | Parent
2 | 1
3 | 2
4 | 2
5 | 2
6 | 2
7 | 2 <-- beginning of the "e" element
8 | 7 <-- first instance of the "e1" element
9 | 8
10 | 8
11 | 8
8 | 7 <-- second instance of the "e1" element
9 | 8
10 | 8
11 | 8
8 | 7 <-- third and final instance of the "e1" element
9 | 8
10 | 8
11 | 8
12 | 2 <-- beginning of the "f" element
13 | 12
14 | 12
15 | 12
相反,我将其作为查询输出的前两列:
Tag | Parent
2 | 1
3 | 2
4 | 2
5 | 2
6 | 2
7 | 2 <-- beginning of the "e" element
12 | 2 <-- beginning of the "f" element
13 | 12
14 | 12
15 | 12
8 | 7 <--first instance of the "e1" element
9 | 8
10 | 8
11 | 8
8 | 7 <-- second instance of the "e1" element
9 | 8
10 | 8
11 | 8
8 | 7 <-- third and final instance of the "e1" element
9 | 8
10 | 8
11 | 8
这显然会生成格式错误的 XML,如下所示:
<elem elem_att1="..." elem_att2="1" elem_att3="...">
<a>...</a>
<b>...</b>
<c>...</c>
<d>...</d>
<e />
<f>
<f1 f1_att1="..." f1_att2="..." />
<f2 f2_att1="..." f2_att2="..." />
<f3 f3_att1="..." f3_att2="..." />
</f>
<e1 e1_att1="..." e1_att2="1">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
<e1 e1_att1="..." e1_att2="2">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
<e1 e1_att1="..." e1_att2="3">
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
</e1>
</e>
</elem>
查询阻塞并引发以下错误:
Msg 6833, Level 16, State 1, Line 2
Parent tag ID 7 is not among the open tags. FOR XML EXPLICIT requires parent tags to be opened first. Check the ordering of the result set.
这是我的条款:order by
order by [elem!2!att2], [e1!8!att2]
如果我将子句更改为order by
order by [elem!2!att2], tag, [e1!8!att2]
查询成功执行,但元素的所有子记录都嵌套在最后一个元素下:e1
e1
<elem elem_att1="..." elem_att2="1" elem_att3="...">
<a>...</a>
<b>...</b>
<c>...</c>
<d>...</d>
<e>
<e1 e1_att1="..." e1_att2="1" />
<e1 e1_att1="..." e1_att2="2" />
<e1 e1_att1="..." e1_att2="3">
<e11>...</e11>
<e11>...</e11>
<e11>...</e11>
<e12><![CDATA[...]]></e12>
<e12><![CDATA[...]]></e12>
<e12><![CDATA[...]]></e12>
<e13><![CDATA[...]]></e13>
<e13><![CDATA[...]]></e13>
<e13><![CDATA[...]]></e13>
</e1>
</e>
<f>
<f1 f1_att1="..." f1_att2="..." />
<f2 f2_att1="..." f2_att2="..." />
<f3 f3_att1="..." f3_att2="..." />
</f>
</elem>
实际问题:
是什么原因导致其子项在子项的种群之前填充在结果集中?f
e
我希望这是一个相对常见的错误,其解决方案足够抽象,无需复制超过 1500 行代码即可中继。
答:
0赞
spodger
10/26/2017
#1
我已经很久没有使用它了,但你试过了吗
order by [elem!2!att2], [e], [e1!8!att2]
或
order by [elem!2!att2], 7, [e1!8!att2]
评论
0赞
Paul Cauchon
10/26/2017
其中第一个会导致错误,指出 [e] 不是有效列,第二个无法更正排序问题。
1赞
spodger
10/26/2017
我说好久不见了!不好意思!:-)
评论
EXPLICIT
CDATA
PATH
CDATA
REPLACE
CDATA
CDATA
CDATA