Использование XML, XPath и XQuery

Tsql теория > Использование XML, XPath и XQuery
26.02.2013 15:16:43



Статья:

нтернет постепенно переходит от роли оОычного транспортного средства доставки электронной почты и представлений данных (т.е. Web-страниц) к роли высокопроизводительного средства обеспечения взаимодействия данных с помощью ориентированной на службы архитектуры и XML. Несмотря на повсеместное распространение технологии XML, архитектору данных следует решить, какую роль отвести XML в создаваемой им модели базы данных. SQL Server 2005/2008/2012 обеспечивает техническое сопровождение практически любого архитектурного решения.

Тип данных XML

Будучи встроенным типом данных SQL Server, тип XML может использоваться любым из перечисленных ниже способов:

¦ объявляться как локальная переменная T-SQL;

¦ использоваться как параметр хранимой процедуры или пользовательской функции;

¦ возвращаться из пользовательской функции;

¦ создаваться как тип данных столбца таблицы.

Тип данных XML позволяет хранить как целый документ XML, так и его фрагмент, при максимальном объеме в 2 Гбайт. Фрагментом могут быть строки одного заказа, в то время как полный документ может содержать данные обо всех заказчиках вместе с их заказами и строками заказов.

Данные XML должны быть хорошо отформированными (т.е. синтаксически корректными) и при необходимости могут проверяться относительно коллекции схемы XML.

Использование типа данных XML имеет ряд существенных преимуществ. Ядро базы данных фактически разделяет отдельные элементы и атрибуты XML, а затем хранит их как обычные двоичные данные, подобно типу VarBinary (max). Дескрипторы XML хранятся как метки, указывающие на фактические данные. Это существенно сокращает объем хранимых данных, повышает производительность и позволяет ядру базы данных использовать индексы XML и передвигаться по данным с помощью XQuery.

Распределение и преобразование

Поскольку тип данных XML является новым, существуют определенные правила преобразования данных из типа XML и в него. В документ XML и его узлы могут быть вставлены любые символьные данные.

Тип данных XML может быть преобразован в следующие связанные символьные типы и получен из них:

¦ Char, VarChar    ¦    VarBinary (max);

¦ NChar, NVarChar    ¦    SQL_Variant (посредством    типа VarChar).

Тип данных XML может быть получен из типов text и ntext, но не может быть преобразован в них.

Ограничения типа XML

В связи с тем, что тип XML хранится не так, как обычные реляционные данные, и имеет вложенный формат, при работе с ним существует ряд дополнительных ограничений.

¦ Его нельзя трактовать как обычные символьные типы.

¦ Он не может участвовать в операциях сравнения (таких как =, > или <), за исключением IS NULL и IS NOT NULL.

¦ Он не может участвовать в сортировке и группировке (т.е. в предложениях SORT BY и GROUP BY).

¦ Он не может использовать встроенные скалярные функции, за исключением isnull О и coalesce().

¦ Он не может быть использован в качестве ключевого столбца или ограничения на уникальность.

¦ Он не может быть объявлен с сопоставлением.

Коллекции схем XML

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

Решение заключается в создании дополнительного (но необязательного) пространства имен определения схемы XML (XSD) и подключения к нему переменной или столбца XML. Схема XML может быть определена для применения к документу в целом или только к его некоторому фрагменту.

Первым шагом является создание XSD как составной части коллекции схемы XML в базе данных. Как только схема будет создана, могут быть также созданы столбцы или переменные, ссылающиеся на нее. В следующем примере в схему учебной базы данных XMLeam добавляется определение XSD с названием ItemSchema:

CREATE DATABASE XMLearn USE XMLearn

CREATE XML SCHEMA COLLECTION ItemSchema AS N'

<xsd:schema xmlns:xsa="http://www.w3.org/200l/XMLSchema" xmlns="resume-schema" targetNamespace="resume-schema" elementFormDefault="qualified">

<xsd:element name="Item" type="ItemType"/>

<xsd:complexType name="ItemType" mixed="true">

<xsd:sequence>

<xsd:element name="SKU" type="xsd:string" minOccurs="1"/>

<xsd:element name="Size" type="xsd:string" minOccurs="1"/>

<xsd:element name="Color" type="xsd:string" minOccurs="1"/>

</xsd:sequence>

</xsd:complexType>

</xsd:schema>'

Чтобы просмотреть установленные схемы, выполните запрос к системному представлению sysxml_schema_col lections.

Когда определение схемы XSD установлено в коллекции схем XML, переменная или столбец с типом XML при создании могут быть подключены к этому определению

Схема XSD также может быть определена и в Management Studio. Свойства столбца содержат пространство имен схемы XSD, которое будет использоваться для выбора XSD из коллекции схем.

SQL Server 2005 не поддерживает старые определения типов документа (DTD), На заметку    используя исключительно XSD.

Индексы XML

Существенным преимуществом использования типа XML является то, что узлы XML сами по себе могут быть проиндексированы. Индексы XML повышают производительность запросов XQuery, однако не используются при извлечении данных XML с помощью реляционных запросов. В моей практике эти индексы зарекомендовали себя очень хорошо. Создание индексов XML является многошаговой операцией, включающей в себя создание первичного и вторичного индексов.

Первичный индекс XML должен создаваться первым. Он связывает узлы XML с реляционным кластеризованным индексом и позволяет создавать индексы, специфичные для XML.

CREATE [ PRIMARY ] XML INDEX имя_индекса ON <объект> ( имя_столбца_хт1 )

[ USING XML INDEX имя_индекса_хт1

[ FOR { VALUE | PATH | PROPERTY } ][ ; ]

Таблица должна иметь кластеризованный индекс, который не может быть изменен, пока существуют индексы XML.

Как только первичный индекс создан, для повышения производительности запросов XQuery могут быть созданы вторичные индексы.

¦ Value. Индексирование данных для поиска по значению.

¦ Path. Индексирование имен узлов для поиска по структуре XML.

¦ Property. Оптимизация предикатов пар “имя-значение”.

Выполнение запросов к данным XML

Когда данные хранятся непосредственно в столбцах с типом XML, для извлечения этих данных, их вставки и обновления можно использовать XPath и XQuery. Язык XQuery является относительно молодым, и работа над ним продолжается в настоящее время.

Если вы когда-либо использовали XPath, считайте, что прошли половину пути в освоении XQuery. Практически все допустимые инструкции XPath являются также и инструкциями XQuery. К тому же XPath используется для отбора значений в выражениях XQuery FLWOR.

Для полного описания языка XQuery и методов слияния реляционных запросов с запросами XQuery могла бы понадобиться толстая книга объемом в тысячу страниц. Однако можно определенно заявить следующее: по мере эволюции технологий работы с данными, XML и XQuery станут неотъемлемой частью любой связанной с данными деятельности.

Xpath

XPath является функцией XML. Она привносит в XML ограничения результатов и средства обобщения при навигации по иерархии XML для доступа к любому узлу (элементу, атрибуту или фрагменту текста) в документе XML. Программный код XPath может быть добавлен для фильтрации данных в стилевую таблицу XSL или в другие запросы XML. Выгоднее всего использовать XPath в шаблонах SQL Server.

Вначале XPath должен идентифицировать узел. Идентификация узла функционально сходна с именем столбца в предложении WHERE инструкции SELECT. Например, для перехода к элементу event, содержащемуся в элементе tour, используется следующая структура: /Tours/Tour/Event

В приведенном примере использована абсолютная адресация. Местонахождение узла может быть указано и относительно текущего положения, чтобы фрагмент XSL, работающий с дочерними данными, мог выбрать узел родителя для процесса фильтрации.

Чтобы спуститься по дереву иерархии XML до атрибута, используется символ @, как в следующем примере:

/Tours/Tour/@Name

После того как идентифицирован корректный узел, XPath позволяет использовать несколько средств фильтрации для отбора корректных данных. Для применения фильтра WHERE = критерий определяется сразу после названия узла и заключается в квадратные скобки:

/Tours/Tour/@Name ['Gauley River Rafting']

В следующем примере используется функция запроса для извлечения данных XPath в реляционном запросе:

SELECT Customer, OrderDetail.query(

'/Items[1]/Item[1] /SKU')

FROM XMLOrders

Запросы FLWOR

Запросы FLWOR являются сердцем языка XQuery. Аббревиатура FLWOR составлена из первых букв последовательности предложений For-Let-Where-Order By-Return. В самом названии заложен синтаксис данных запросов. Это аналогично последовательности операций в обычном реляционном запросе SELECT, однако запросы FLWOR последовательно проходят по иерархическим данным XML.

Назначение предложения For соответствует одноименному предложению в языке SQL. Так как язык XQuery проектировался разработчиками приложений, а не баз данных, под конструкцией For на самом деле подразумевается конструкция For Each, которая предполагает последовательное прохождение по всем элементам. Это раскрывает не пакетный характер мышления в XML.

Предложение Let используется для присвоения значения переменным, которые в дальнейшем будут участвовать в запросе XQuery. В SQL Server 2005 ключевое слово Let не поддерживается.

Назначение предложения Where идентично его назначению в SQL— оно ограничивает элементы и атрибуты XML, отбираемые запросом.

Предложение Order By также будет интуитивно понятно программистам SQL. Предложение Return специфично для языка XQuery. Этот креативный синтаксис используется для конфигурирования формата данных XML, возвращаемых запросом XQuery.

SELECT Customer, OrderDetail.query(

'for $i in /Items/Item where $i/Quantity = 2 return $i/SKU1)

FROM XMLOrders

Как будет показано в следующем разделе, запросы XQuery используют в функциях реляционных запросов.

Слияние XQuery с инструкцией select

Запросы XQuery в SQL Server слегка отличаются от стандарта. Причиной этому стало то, что стандарт XQuery создавался для извлечения данных из файлов XML, в то время как методы XQuery в SQL Server предназначены для интеграции в инструкции SELECT.

Метод exist проверяет наличие заданного узла, аналогично синтаксису IF EXISTS языка SQL:

SELECT Customer FROM XMLOrders WHERE OrderDetail.exist(

1/Items/Item[SKU = 234]')=1

Метод exist возвращает значение 1, если узел существует, или 0 — в противном случае: Name

Sam

Метод value возвращает фактическое значение узла; он может вернуть только скалярное значение:

SELECT Customer,OrderDetai1.value(

'/Items[1]/Item[1]/SKU[1]',    'VARCHAR(25)')

FROM XMLOrders

Метод query позволяет запросу XQuery вернуть в реляционный запрос SELECT данные в полном объеме:

SELECT Customer, OrderDetail.query(

'for $i in /Items/Item return $i/SKU')

FROM XMLOrders

Метод nodes является, пожалуй, самым полезным при работе с XQuery. Он возвращает набор строк, который может быть объединен с реляционными данными в запросе SELECT.

Последний метод, modify, используется для изменения значений в переменных или столбцах с типом XML. Этот метод предназначен для использования в инструкции UPDATE и может изменять данные с помощью команд insert, delete и replace:

UPDATE XMLOrders

SET OrderDetail.modify(

'insert

dtems SKU = n678" Quantity = "2n/> into /Items[1] *

)

WHERE OrderlD = 1

UPDATE XMLOrders

SET OrderDetail.modify(

'delete /Items/Item[1]1 )

WHERE OrderlD = 1

Декомпозиция данных XML в SQL Server

Одним из вариантов работы с данными XML является их декомпозиция с последующим сохранением элементов в реляционных таблицах. В настоящий момент SQL Server 2005 позволяет создавать и читать данные XML с помощью инструкции SELECT.

Чтение данных XML в SQL Server

Приложения читают данные XML с помощью процедуры синтаксического разбора, которая, в свою очередь, представляет данные XML объектной модели документа (DOM). Этот установленный консорциумом W3C стандарт является объектно-ориентированным представлением документа XML. Сам документ XML и каждый элемент, атрибут или текст в нем становится объектом DOM. Объектная модель документа является очень мощной и может использоваться в объектно-ориентированном программном коде для создания, чтения и модификации документа XML.

SQL Server использует процедуру разборки XML и объектную модель документа от Microsoft для чтения документа XML в два этапа.

1. Хранимая процедура sp_xml_preparedocument читает документ XML с помощью алгоритма синтаксического разбора MSXML, после чего создает внутренние объекты DOM в SQL Server. Объекты DOM идентифицируются целыми числами, возвращаемыми этой хранимой процедурой.

2. В инструкции SQL DML в качестве источника данных используется функция OpenXML, которая идентифицирует объект DOM с помощью целого числа, возвращенного хранимой процедурой sp_xml_preparedocument.

В приведенном ниже примере мы вначале присваиваем данные XML локальной переменной @XML. После этого SQL Server читает данные в SQL, используя результаты предыдущих двух этапов.

1. В результате выполнения хранимой процедуры sp_xml_preparedocument создаются объекты DOM.

2. Инструкция SELECT обращается к системной функции OpenXML как к источнику данных. Эта функция принимает три параметра.

• Целочисленный идентификатор внутреннего объекта DOM, который хранится в переменной @iDOM.

• Шаблон документа XML rowpattern, который функция OpenXML использует для идентификации структуры элементов данных XML. В данном случае значением параметра rowpattern является ' /Tours/Tour/Event1.

• Флаг конфигурации XML, определяющий, как элементы и атрибуты будут интерпретироваться функцией XML (табл. 31.1).

3. Параметр WITH приводит в действие механизм проверки соответствия столбцов с возвращаемом функцией OpenXML в результирующем наборе данных. Столбец определяется именем XML, типом данных и необязательным параметром местонахождением элемента.

Таблица 31.1. Флаги конфигурации функции орепхмь

Значение флага

Режим работы

Описание

0

По умолчанию

По умолчанию ищет атрибуты

1

Основанный на атрибутах

Функция ищет атрибуты

2

Основанный на элементах

Функция ищет элементы

8

Комбинированный

Функция ищет атрибуты, а затем элементы

Пакет завершается вызовом хранимой процедуры sp_removedocument, которая удаляет объектную модель документа из памяти:

DECLARE

@iDOM int,

@XML VarChar(8000)

Set @XML = '

<?xml version="l.0" encoding="UTF-8"?>

<Tours>

<Tour Name="Amazon Trek">

<Event Code="01-003" DateBegin="2001-03-16T00:00:00"/>

<Event Code="01-015" DateBegin="2001-ll-05T00:00:00"/>

</Tour>

<Tour Name="Appalachian Trail">

<Event Code="01-005" DateBegin="2001-06-25T00:00:00"/>

<Event Code="01-008" DateBegin="2001-07-14T00:00:00"/>

<Event Code="01-010" DateBegin="2001-08-14T00:00:00"/>

</Tour>

<Tour Name="Bahamas Dive">

<Event Code="01-002" DateBegin="2001-05-09T00:00:00"/>

<Event Code="01-006" DateBegin="2001-07-03T00:00:00"/>

<Event Code="01-009" DateBegin="2001-08-12T00:00:00"/>

</Tour>

<Tour Name="Gauley River Rafting">

<Event Code="01-012" DateBegin="2001-09-14T00:00:00"/>

<Event Code="01-013" DateBegin="2001-09-15T00:00:00"/>

</Tour>

<Tour Name="Outer Banks Lighthouses">

<Event Code="01-001" DateBegin="2001-02-02T00:00:00"/>

<Event Code="01-004" DateBegin="2001-06-06T00:00:00"/>

<Event Code="01-007" DateBegin="2001-07-03T00:00:00"/>

<Event Code="01-011" DateBegin="2001-08-17T00:00:00"/>

<Event Code="01-014" DateBegin="2001-10-03T00:00:00"/>

<Event Code="01-016" DateBegin="2001-ll-16T00:00:00"/>

</Tour>

</Tours>1

-- Генерирование внутренней объектной модели документа ЕХЕС sp_xml_preparedocument @iDOM OUTPUT, @XML

-- Поставщик OPENXML SELECT *

FROM OPENXML (@iDOM, '/Tours/Tour/Event8) WITH ([Name] VARCHAR(25)    '../@Name',

Code VARCHAR(10),

DateBegin DATETIME )

EXEC sp_xml_removedocument @iDOM

Будут получены следующие результаты (сокращенно):

Name

Code

DateBegin

Amazon Trek Amazon Trek Appalachian Trail Appalachian Trail

01-003

01-015

01-005

01-008

2001-03-16

2001-11-05

2001-06-25

2001-07-14

00:00:00.000

00:00:00.000

00:00:00.000

00:00:00.000

Создание документов XML в SQL Server 2005

В SQL Server 2005 можно создавать документы XML непосредственно в запросах. Необязательный суффикс FOR XML инструкции SELECT дает указание серверу форматировать результат запроса как документ XML, а не стандартный набор данных SQL.

Вывод XML направляется в один столбец. По умолчанию параметр maximum На заметку    size per column анализатора запросов установлен в слишком малое зна-

^    чение, чтобы можно было просмотреть результирующий набор данных в фор

мате XML. Во вкладке Results диалогового окна Options этот параметр можно установить в значение 8192. Открывается диалоговое окно параметров с помощью пункта меню Tools^Options.

Суффикс FOR XML позволяет сформировать данные XML, но не сам раздел объявлений корневого элемента root. Чтобы получить хорошо сформированный документ XML, приложению нужно “облачить” данные, полученные от SQL Server, в корректную оболочку.

Режим FOR XML RAW

Суффикс FOR XML имеет три режима: RAW, AUTO и ELEMENTS. Режим FOR XML RAW сбрасывает строки результирующего набора данных в документ XML, не генерируя при этом какую-либо иерархическую структуру. Каждая строка SQL становится элементом raw документа XML:

SELECT Tour.Name, Event.Code, Event.DateBegin FROM Tour JOIN Event

ON Tour.TourlD = Event.TourlD FOR XML RAW

Будет получен следующий результат (сокращенно):

<row Name="Amazon Trek" Code="01-0 03"

DateBegin="2 001-03-16T00:00:00"/>

<row Name="Amazon Trek" Code="01-015"

DateBegin="2001-11-05T00:00:00"/>

<row Name= "Appalachian Trail" Code=1101-0 05"

DateBegin="2 001-06-25T00:00:00"/>

<row Name="Appalachian Trail" Code="01-008"

DateBegin="2 001-07-14T00:00:00"/>

<row Name="Appalachian Trail" Code="01-010" DateBegin="2001-08-14T0 0:00:00"/>

Режим FOR XML AUTO

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

SELECT Tour.Name, Event.Code, Event.DateBegin FROM Tour JOIN Event

ON Tour.TourlD = Event.TourlD FOR XML AUTO

Параметр ELEMENTS указывает режиму FOR XML AUTO генерировать элементы вместо атрибутов. Следующий вариант документа XML использует параметр ELEMENTS для генерирования исключительно элементов:

SELECT Tour.Name, Event.Code, Event.DateBegin FROM Tour JOIN Event

ON Tour.TourlD = Event.TourlD FOR XML AUTO, ELEMENTS

Будет получен следующий результат (сокращенно):

<Tour>

<Name>Amazon Trek</Name>

<Event>

<Code>01-003</Code>

<DateBegin>2001-03-16T00:00:00</DateBegin>

</Event>

<Event>

<Code>01-015</Code>

<DateBegin>2001-ll-05T00:00:00</DateBegin>

</Event>

</Tour>

<Tour>

<Name>Appalachian Trail</Name>

<Event>

<Code>01-005</Code>

<DateBegin>2001-06-25T00:00:00</DateBegin>

</Event>

<Event>

<Code>01-008</Code>

<DateBegin>2001-07-14T00:00:00</DateBegin>

</Event>

<Event>

< Code >01-010</Code >

<DateBegin>2001-08-14T00:00:00</DateBegin>

</Event>

</Tour>

Дополнительная Служба интеграции SQL Server 2005 также поддерживает импорт и экспорт информация    данных XML.

Резюме

Согласитесь вы с идеей хранения XML в базе данных или нет, XML прочно вошел в нашу жизнь, и знание этой технологии критично для любого профессионала баз данных. Архитектура, ориентированная на службы, частично базируется на концепции самоописательных документов XML. XQuery рассматривается как ключевая технология взаимодействия с данными XML. XML перестал быть словесным заменителем текстовых данных с разделителями — он стал обобщенным языком обмена данными.