loading..
Русский    English
14:54
листать

Методы типа данных XML стр. 6

Метод nodes()

Разбивает XML-структуру на одно или несколько поддеревьев, в соответствии с указанным выражением XPath.

Выполним следующий запрос:

  1. SELECT name AS artist
  2.     , album.query('.') AS album
  3. FROM dbo.tArtist A
  4. CROSS APPLY A.xmlData.nodes('/albums[1]/album')col(album);

Данный запрос разобьет исходную структуру на строки, по количеству элементов "album" и вернет по две строки для каждого исполнителя:

artist            album
Radiohead        <album title="The King of Limbs"><labels><label>S...
Radiohead        <album title="OK Computer"><labels><label>Parlop...
Guns N' Roses       <album title="Use Your Illusion I"><labels><label>G...
Guns N' Roses        <album title="Use Your Illusion II"><labels><label>G...

Разберем текст запроса подробнее.

CROSS APPLY A.xmlData.nodes('/albums[1]/album') – разбивает каждую строку таблицы на столько строк, сколько элементов "album" было найдено.

col – это имя производной таблицы, а album – это имя столбца. Они нужны будут для дальнейшей работы с результатами.

album.query('.') – здесь осуществляется запрос к каждой строке результатов, при помощи псевдонима. Данный подзапрос просто выбирает все данные из поддерева.

Разберём другой пример. Допустим мы хотим получить в виде таблицы первые две песни каждого альбома для каждой из групп.

  1. SELECT name AS artist
  2.     , song.value('../@title', 'varchar(50)') AS album
  3.     , song.value('@title', 'varchar(100)') AS song
  4. FROM dbo.tArtist A
  5. CROSS APPLY A.xmlData.nodes('/albums[1]/album/song[position()<=2]')col(song);

artist        album            song
Radiohead    The King of Limbs    Bloom
Radiohead    The King of Limbs    Morning Mr Magpie
Radiohead    OK Computer    Airbag
Radiohead    OK Computer    Paranoid Android
Guns N' Roses    Use Your Illusion I    Right Next Door to Hell
Guns N' Roses    Use Your Illusion I    Dust N' Bones
Guns N' Roses    Use Your Illusion II    Civil War
Guns N' Roses    Use Your Illusion II    14 Years

[position()<=2] – указывает, что нам нужны только два первых элемента "song" внутри каждого элемента "album".

'../@title' – обращается к родительскому элементу и берёт его атрибут @title.

Результат отобразился корректно, но при больших объёмах данных такой запрос будет крайне медленным и неэффективным. Причина заключается в том, что для каждой песни среда выполнения запроса ищет родительский элемент и считывает его атрибут. Перепишем запрос следующим образом:

  1. SELECT name AS artist
  2.     , album.value('@title', 'varchar(50)') AS album
  3.     , song.value('@title', 'varchar(100)') AS song
  4. FROM dbo.tArtist A
  5. CROSS APPLY A.xmlData.nodes('/albums[1]/album')c1(album)
  6. CROSS APPLY c1.album.nodes('song[position()<=2]')c2(song);

Результат будет аналогичным, однако теперь логика запроса изменена следующим образом: сначала выбираются все альбомы, а потом для каждого альбома будут присоединяться песни.

Поскольку песен всегда будет намного больше, чем альбомов, выполнение данного запроса покажет существенный прирост производительности по сравнению с предыдущим.


Bookmark and Share
Страницы: 1 2 3 4 5 6
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INFORMATION_SCHEMA INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker Больше тэгов
Учебник обновлялся
месяц назад
продать payeer . Правильное выполнение дуг для парника
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.