1

Is there a generic way, in T-SQL, to iterate through an xml variable and get the xml for each entity in turn?

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>'

For example, in the above XML, there are three instances of Entity. I want the XML for each one in turn. I can do this in a hard-coded way, e.g.

SELECT @entityxml = @xml.query('/Entities/Entity[1]')

which will return

    <Entity key="4" attrib1="abc" attrib2="def" />

I can then change it to a [2] to get the next one, and so forth.

But, according to both BOL and experimentation, the parameter to @xml.query must be a string literal. In other words, a variable can't be used as the parameter, building it with [1], [2], etc., and getting however many entities there are. It appears we have hard-code the queries, which makes for some ugly code.

I know other methods can be used to get the data in the xml into a table, and then iterate through the rows in the table. I'm specifically asking about getting the XML itself, i.e. getting the equivalent of the above @xml.query, but being able to do so without having to hard-code the array value.

Thanks!

4

2 回答 2

3

您可以使用position()根据索引选择元素:

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>'

declare @i int;
set @i = 2;

select @xml.query('Entities/Entity[position()=sql:variable("@i")]');
于 2013-05-11T00:58:51.497 回答
0

像这样的东西可以解决问题:

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>';

SELECT @xml.query('
for $i in //Entity
return
<Entity>
    { $i/@key }
    { $i/@attrib1 }
    { $i/@attrib2 }
</Entity>
');
于 2013-05-10T22:29:04.543 回答