FROM OPENXML
с соответствующими СП для подготовки и удаления документа устарели и больше не должны использоваться. Вместо этого используйте соответствующие методы, которые предоставляет тип данных XML .
Порядок элементов является неотъемлемой частью документа XML. Это не лучший дизайн, но можно связать информацию через их относительное положение . Очевидно, у вас возникнут проблемы, если здесь чего-то не хватает.
Я не понял, как <sex>
связан и что ваши <mmx>
и <pbx>
здесь делают, но вы можете идти по этой дороге:
DECLARE @xml XML=
N'<person>
<keys>
<key>xx8546</key>
<key>yy369</key>
</keys>
<sex>f</sex>
<names>
<name>
<prename>Sarah</prename>
<surname>Connor</surname>
</name>
<name>
<prename>Sarah</prename>
<surname>Williams</surname>
</name>
</names>
</person>';
Запрос начинается с внутри строки . Количество ключей возвращается как производная таблица. В этом случае Tally
вернет set из 1
и 2
.
Теперь вы можете использовать этот рабочий номер, чтобы получить коррелированные данные из вашего XML:
WITH Tally(Nr) AS (SELECT TOP (@xml.value(N'count(/person/keys/key)','int')) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values)
SELECT Nr
,@xml.value(N'(/person/keys/key[sql:column("Nr")]/text())[1]','nvarchar(max)') AS PersonKey
,@xml.value(N'(/person/names/name[sql:column("Nr")]/prename/text())[1]','nvarchar(max)') AS PersonPrename
,@xml.value(N'(/person/names/name[sql:column("Nr")]/surname/text())[1]','nvarchar(max)') AS PersonSurname
-- this will return the <sex> for both (as there is just one...)
,@xml.value(N'(/person/sex/text())[1]',N'nvarchar(max)') AS sex
FROM Tally;
Результат
Nr PersonKey PersonPrename PersonSurname sex
1 xx8546 Sarah Connor f
2 yy369 Sarah Williams f