Алексей Немиро
Чтение XML
SQL Server, еще с 2000 года, имеет набор стандартных средств для работы с XML. В частности, в базе данных можно хранить данные типа XML, создавать их налету и читать.
Поскольку XML как таковой является строкой, то для того чтобы SQL Server мог работать с XML как с набором данных, нужно ему об этом рассказать. Сделать это можно при помощи системной хранимой процедуры sp_xml_preparedocument. Процедураsp_xml_preparedocument создает представление указанного XML-документа (по сути, таблица) и передает его дескриптор (идентификатор, числовой код). Последующая работа с XML происходит именно через дескриптор, посредствам функции OPENXML. После завершения работы, документ можно удалить при помощи процедуры sp_xml_removedocument, хотя это делать вовсе и не обязательно, поскольку данные и так удалятся по завершению работы текущей сессии. Чтобы было более понятно, о чем идет речь, давайте рассмотрим простой пример чтения XML.
02 |
DECLARE @data nvarchar( max ); |
10 |
exec sp_xml_preparedocument @h OUTPUT , @data; |
12 |
SELECT * FROM OPENXML (@h, '/www/site' ) |
13 |
WITH ([ name ] nvarchar(50), [url] nvarchar(100)); |
15 |
exec sp_xml_removedocument @h; |
Как видите, у нас есть две переменные. Переменная @h имеет числовой тип данных, она предназначена для хранения ссылки на дескриптор представления XML. Переменная @data имеет строкой тип данных, которая служит для передачи XML. Системная процедура sp_xml_preparedocument создает на основе указанных в переменной @data данных представление XML и передает в переменную @h ссылку на это представление.
Затем, при помощи инструкции SELECT FROM выводятся данные XML-документа, сформированные в функции OPENXML. Первый параметр функции OPENXML указывает ссылку на дескриптор документа XML, второй параметр указывает ветку, из которой нужно провести выборку данных. Так, в приведенном примере, берутся все элементы site, относящиеся к элементу www. Далее, операторWITH указывает имена атрибутов и выходящий тип данных, которые будут переданы в таблицу. У нас выводятся все атрибуты: nameтипа nvarchar(50), url типа nvarchar(100). Если, например, убрать url, то в выдаче просто не будет такой колонки. Если указать неверный тип данных, то может произойти ошибка. Если указать несуществующее имя, то в выдаче поле будет иметь значение NULL.
Функция OPENXML также может принимать и третий параметр - flags, который указывает на тип сопоставления, по умолчанию он имеет нулевое значение - сопоставление по атрибутам. Именно поэтому, в указанном выше примере данные выводятся из XML-атрибутов, а не элементов. Параметр flasg может принимать следующие значения:
0 - значение по умолчанию, как уже было сказано, будет использоваться атрибутная модель сопоставления;
1 - приоритетно используется атрибутная модель, а сопоставление с использованием элементов на втором плане;
2 - сопоставление с использованием элементов;
8 - позволят выбрать метод и приоритет сопоставления.
Т.е. если требуется вывести данные из элементов, то нужно использовать опцию 2, как показано в следующем примере.
02 |
DECLARE @data nvarchar( max ); |
06 |
<name>Портал для программистов</name> |
10 |
<name>Поисковая система</name> |
14 |
<name>Социальная сеть</name> |
19 |
</strong> exec sp_xml_preparedocument @h OUTPUT , @data; |
21 |
SELECT * FROM OPENXML (@h, '/www/site' , 2) |
22 |
WITH ([ name ] nvarchar(50), [url] nvarchar(100)); |
24 |
exec sp_xml_removedocument @h; |
Рис. 1. Вывод XML в SQL Server в виде таблицы.
Как видите, все относительно просто, хотя может быть и еще проще. Начиная с SQL Server 2005 появился тип данных XML, который позволяет обходиться без всего выше описанного. Тип данных XML имеет встроенные методы, которые дают возможность работать с XML без создания дескрипторов.
10 |
n.value( '@name' , 'nvarchar(50)' ) AS name , |
11 |
n.value( '@url' , 'nvarchar(100)' ) AS url |
12 |
FROM @data.nodes( '/www/site' ) AS node(n) |
В этом примере данные берутся напрямую из указанного документа при помощи метода nodes и каждая пачка данных передается в поле n (имя может быть любым) типа node. Значение из конкретного атрибута берется при помощи функции value, которая принимает два параметра. Первый параметр указывает имя XML-сущности, в данном случае, символ "собака" (@) говорит о том, что нужно получить значение из атрибута. Использовать атрибуты достаточно просто, именно поэтому они фигурируют во всех примерах данной статьи. Работа с элементами может показаться несколько сложной для понимания.
05 |
<name>Портал для программистов</name> |
09 |
<name>Поисковая система</name> |
13 |
<name>Социальная сеть</name> |
19 |
n.value( 'name[1]' , 'nvarchar(50)' ) AS name , |
20 |
n.value( 'url[1]' , 'nvarchar(50)' ) AS url |
21 |
FROM @data.nodes( '/www/site' ) AS node(n) |
В пример, каждый элемент site теоретически может иметь множество вложенных элементов name и url, т.е. фактически каждый из этих элементов является массивом. Именно поэтому в квадратных скобках указывается индекс элемента, в нашем случае это единица (отсчет начинается с 1).
Тип данных XML имеет та же и другие методы, такие как query, exist, modify, но в рамках данной статьи я их рассматривать не буду, если у вас возникнет потребность в использовании этих методов, вам всегда помогут на форуме для программистов.
Выдача XML
Создавать XML гораздо проще чем, читать. Во-первых, можно сгенерировать XML в обычной строковой переменной, как показано в следующем примере. Собственно, так можно сделать не только в SQL Server, но и в других СУБД.
01 |
-- временная таблица, чтобы было на чем показывать пример |
02 |
CREATE TABLE #tmp (id int identity, name nvarchar(50), url nvarchar(100)); |
11 |
-- основная часть примера |
13 |
DECLARE @xml AS nvarchar(1000); |
15 |
SELECT @xml = @xml + '<site name="' + name + '" url="' + url + '" />' FROM #tmp; |
16 |
SET @xml = @xml + '<www>' ; |
20 |
-- удаляем временную таблицу |
Во-вторых, в SQL Server 2005 появились средства, которые позволяют буквально парой дополнительных команд превратить любую таблицу в XML. Для выдачи результатов в XML-формате, в инструкции SELECT FROM нужно использовать команду FOR XML. Эта команда умеет генерировать XML в нескольких режимах: RAW, AUTO, EXPLICIT и PATH.
1 |
SELECT * FROM #tmp FOR XML AUTO; |
Рис. 2. Результат автоматического формирования XML.
Режим RAW и AUTO самые простые. RAW создает для каждой строки данных XML-элемент, по умолчанию, с именем row, где в качестве атрибутов выступают колонки таблицы. Режим AUTO генерирует XML в зависимости от представленных данных, в нашем случае получается результат совсем далекий от ожидаемого. Более гибкие и, соответственно, сложные режимы это EXPLICIT и PATH.
01 |
-- временная таблица, чтобы было на чем показывать пример |
02 |
CREATE TABLE #tmp (id int identity, name nvarchar(50), url nvarchar(100)); |
11 |
-- основная часть примера |
12 |
SELECT name , url FROM #tmp FOR XML PATH( 'site' ), ROOT( 'www' ); |
14 |
-- удаляем временную таблицу |
Рис. 3. Результат формирования XML в режиме PATH.
В этом примере используется режим PATH, первый, и единственный обязательный, параметр которого содержит имя основного элемента - site, в который будут вложены значения полей таблицы. Директива ROOT указывает имя родительской ветки - www. Если требуется изменить имена элементов XML, то это можно сделать стандартными средствами SQL, т.е. путем создания алиасов (синонимов). Символ "собаки" (@) в имени алиса превратит колонку в выдаче в XML-атрибут.
1 |
SELECT name AS 'the_name' , url AS '@address' FROM #tmp FOR XML PATH( 'site' ), ROOT( 'www' ); |
Ссылки по теме