XML NODES: примеры (SQL)
XML_NODES(XQuery as TableColumn): TABLEОписание функции XML_NODES
Функция XML_NODES в MS SQL Server служит для разбора XML-документа и возврата набора строк, где каждая строка соответствует одному узлу, выбранному с помощью указанного выражения XQuery. Она используется в случаях, когда необходимо преобразовать иерархическую XML-структуру в реляционный табличный формат для последующей обработки средствами T-SQL.
Аргументы функции:
- XQuery: Выражение языка XQuery, которое определяет узлы для извлечения из XML-документа. Это строковый литерал.
- RowPattern: Необязательный строковый аргумент, который определяет имя столбца в результирующей таблице. По умолчанию используется имя 'node'.
Возвращаемое значение:
Функция возвращает таблицу с одним столбцом. Тип данных этого столбца — XML. Каждая строка таблицы содержит XML-фрагмент, соответствующий узлу, найденному по выражению XQuery. Для извлечения конкретных значений из этих узлов обычно используют операторы CROSS APPLY или OUTER APPLY в сочетании с функциями типа value() или query().
Краткие примеры использования
Извлечение всех узлов из документа.
DECLARE @xml XML = ' ';
SELECT n.value('@id', 'INT') AS BookId
FROM @xml.nodes('/Catalog/Book') AS T(n);BookId
------
1
2
Использование с указанием имени столбца для узлов.
DECLARE @xml XML = '- A
';
SELECT myNodeColumn.query('.') AS NodeXML
FROM @xml.nodes('/root/item', 'myNodeColumn') AS T(myNodeColumn);NodeXML
------------- A
Похожие функции в MS SQL Server
XML_VALUE: Извлекает скалярное значение из XML-документа по указанному XPath. Используется, когда требуется одно значение, а не набор узлов. Предпочтительнее для простого извлечения атрибутов или текстового содержимого.
XML_QUERY: Возвращает фрагмент XML типа XML по указанному XPath-выражению. Применяется, когда необходимо получить поддерево XML в его исходном формате.
OPENXML: Устаревшая, но функциональная альтернатива для разбора XML, которая предоставляет реляционное представление документа через системные хранимые процедуры. Требует больше ресурсов и менее эффективна по сравнению с XML_NODES для большинства сценариев.
Типичные ошибки при использовании
Неправильный XPath-путь приводит к пустому результату, а не к ошибке.
DECLARE @xml XML = ' ';
SELECT n.value('@id', 'INT') AS BookId
FROM @xml.nodes('/Invalid/Path') AS T(n);BookId
------
(0 rows affected)
Попытка извлечь несуществующий атрибут или узел с функцией value() может вернуть NULL.
DECLARE @xml XML = ' ';
SELECT n.value('@missing', 'INT') AS Attr
FROM @xml.nodes('/Book') AS T(n);Attr
-----
NULL
Использование функции без указания алиаса для таблицы вызывает ошибку синтаксиса.
DECLARE @xml XML = ' ';
SELECT value('@id', 'INT') FROM @xml.nodes('/root'); -- ОшибкаИзменения в последних версиях
Функция XML NODES была введена в SQL Server 2005. Существенных изменений в её синтаксисе или поведении в более поздних версиях, включая SQL Server 2019 и 2022, не зафиксировано. Основные улучшения связаны с общим развитием движка XML и оптимизацией запросов.
Расширенные примеры применения
Обработка вложенных структур с использованием CROSS APPLY.
DECLARE @xml XML = 'A B C ';
SELECT OrderNode.value('@id', 'INT') AS OrderId,
ProdNode.value('.', 'VARCHAR(10)') AS ProductName
FROM @xml.nodes('/Orders/Order') AS O(OrderNode)
CROSS APPLY OrderNode.nodes('Product') AS P(ProdNode);OrderId ProductName
------- -----------
101 A
102 B
102 C
Извлечение данных из разных типов узлов в одном запросе.
DECLARE @xml XML = '- Value1
- Value2
';
SELECT n.value('@type', 'CHAR(1)') AS Type,
n.value('.', 'VARCHAR(10)') AS Value
FROM @xml.nodes('/Data/Item') AS T(n);Type Value
---- ------
A Value1
B Value2
Использование с переменными в XQuery для фильтрации.
DECLARE @xml XML = ' ';
DECLARE @id INT = 2;
SELECT n.value('@id', 'INT') AS FoundId
FROM @xml.nodes('/Items/Item[@id=sql:variable("@id")]') AS T(n);FoundId
-------
2
Аналоги функции в других СУБД
Oracle: Использует функции XMLTABLE для преобразования XML в строки. Отличие в более декларативном синтаксисе для сопоставления столбцов.
SELECT * FROM XMLTABLE('/Catalog/Book' PASSING XMLTYPE('<Catalog><Book id="1"/></Catalog>') COLUMNS id INT PATH '@id');ID
--
1
PostgreSQL: Функция xmltable аналогична Oracle, но с некоторыми синтаксическими особенностями.
SELECT * FROM xmltable('//Book' PASSING ' '::xml COLUMNS id int PATH '@id');id
---
1
MySQL: Не имеет прямой аналогии. Для разбора XML обычно применяются строковые функции или извлечение через ExtractValue и UpdateXML, что менее мощно.
SQLite: Не поддерживает встроенную обработку XML. Разбор требует использования сторонних расширений или обработки на стороне приложения.