Работа с XML в SQL Server (часть 1)

Работа с XML в SQL Server (часть 1)

Поддержка XML впервые появилась в SQL Server 2000 - в язык T-SQL были добавлены ключевые слова FOR XML и OPENXML, которые позволяли разработчикам, соответственно, извлекать результаты запросов к базам данных в виде XML-потока и сохранять XML-документы в базе данных. Эти возможности были существенно расширены в SQL Server 2005 - был введен новый тип данных XML, поддерживающий проверку на уровне XSD_схемы, выполнение XQuery_операций и индексирование. В SQL Server 2008 возможности по работе с XML, как со встроенным типом данных, еще больше расширены.

Начнем с того, что кратко вспомним ключевые возможности по работе с XML, реализованные в предыдущих версиях SQL Server - SQL Server 2000 и SQL Server 2005.
Как я отметил выше, в SQL Server 2000 в язык T-SQL были добавлены ключевые слова FOR XML и OPENXML. FOR XML - это атрибут команды SELECT, указывающий на то, что результаты выполнения запроса должны быть представлены в виде XML-потока. Пример использования данной функциональности показан ниже. Следующий запрос:
SELECT ProductID, ProductName
FROM Products Product
FOR XML AUTO
 
вернет следующий XML-документ:
<Product ProductID="1" ProductName="Widget"/>
<Product ProductID="2" ProductName="Sprocket"/>
Функция OPENXML предназначена для выполнения обратных действий - создания записи на основе переданного ей XML-документа. Пример использования данной функциональности показан ниже. Следующий запрос:
DECLARE @doc nvarchar(1000)
SET @doc = '<Order OrderID = "1011">
<Item ProductID="1" Quantity="2"/>
<Item ProductID="2" Quantity="1"/>
</Order>'
DECLARE @xmlDoc integer
EXEC sp_XML-preparedocument @xmlDoc OUTPUT, @doc
SELECT * FROM
OPENXML (@xmlDoc, 'Order/Item', 1)
WITH
(OrderID integer '../@OrderID',
ProductID integer,
Quantity integer)
EXEC sp_XML-removedocument @xmlDoc
 приведет к созданию такой записи:
OrderID ProductID Quantity
1011 1 2
1011 2 1
Обратите внимание на использование хранимых процедур sp_XML-preparedocument и sp_XML-removedocument для создания XML-документа в памяти и его удаления после записи в базу данных.

В SQL Server 2005 атрибут FOR XML был расширен возможностью задания новых опций для корневых элементов и имен элементов документа, была включена поддержка вложенных вызовов запросов с FOR XML, позволяющих создавать сложные иерархии внутри XML-документов, а также новый режим PATH, позволяющий описать структуру получаемого XML-документа с помощью синтаксиса XPath. Пример использования данной функциональности показан ниже. Следующий запрос:
SELECT ProductID AS '@ProductID',
ProductName AS 'ProductName'
FROM Products
FOR XML PATH ('Product'), ROOT ('Products')
создаст такой XML-документ:
<Products>
 <Product ProductID="1">
  <ProductName>Widget</ProductName>
 </Product>
 <Product ProductID="2">
  <ProductName>Sprocket</ProductName>
 </Product>
</Products>
 
Помимо расширений функциональности, впервые появившейся в SQL Server 2000, в SQL Server 2005 появился встроенный тип данных XML, использование которого позволяет создавать переменные и колонки для хранения XML-данных. Пример использования данной функциональности показан ниже.
CREATE TABLE SalesOrders
 (OrderID integer PRIMARY KEY,
 OrderDate datetime,
 CustomerID integer,
 OrderNotes xml)
 Тип данных xml может использоваться для хранения в базе данных отформатированных документов (HTML, XML, XHTML и т. п.) или полуструктурированных данных. Можно хранить нетипизованные или типизованные XML-данные - последние могут быть проверены на соответствие XSD-схеме. Для задания схемы, используемой для проверки вводимых данных, используется команда СREATE XML SCHEMA COLLECTION:
CREATE XML SCHEMA COLLECTION ProductSchema AS
 '<?xml version="1.0" encoding="UTF_16"?>
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <!- Здесь располагается сама схема ->
 </xs:schema>'

После того как схема описана, она ассоциируется с XML-переменной или колонкой соответствующего типа - пример показан ниже.
CREATE TABLE SalesOrders
 (OrderID integer PRIMARY KEY,
 OrderDate datetime,
 CustomerID integer,
 OrderNotes xml(ProductSchema))
Проверка типизованного XML на соответствие ассоциированной с переменной или колонкой соответствующего типа схеме происходит при записи или обновлении данных - эта возможность позволяет, например, гарантировать соответствие вводимых данных принятым стандартам или обеспечить совместимость с документами различных типов.
Тип данных xml также поддерживает ряд методов, которые могут использоваться для выполнения запросов или манипуляции с XML-данными. Например, можно использовать метод query для выборки данных, как это показано в следующем примере:
declare @x xml
set @x=
 '<Invoices>
 <Invoice>
 <Customer>Kim Abercrombie</Customer>
 <Items>
 <Item ProductID="2" Price="1.99" Quantity="1" />
 <Item ProductID="3" Price="2.99" Quantity="2" />
 <Item ProductID="5" Price="1.99" Quantity="1" />
 </Items>
 </Invoice>
 <Invoice>
 <Customer>Margaret Smith</Customer>
 <Items>
 <Item ProductID="2" Price="1.99" Quantity="1"/>
 </Items>
 </Invoice>
 </Invoices>'
 SELECT @x.query(
 '<CustomerList>
 {
 for $invoice in /Invoices/Invoice
 return $invoice/Customer
 }
 </CustomerList>')
 
В приведенном выше запросе используется XQuery_синтаксис, с помощью которого ищутся все элементы Invoice, находящиеся в данном документе, и возвращается XML-документ, который содержит элемент Customer для каждого элемента Invoice - пример результирующего документа показан ниже.
<CustomerList>
 <Customer>Kim Abercrombie</Customer>
 <Customer>Margaret Smith</Customer>
</CustomerList>
 
Другая новинка, относящаяся к поддержке XML и появившаяся в SQL Server 2005 - это поддержка XML-индексов. Имеется возможность создания первичных и вторичных XML-индексов для колонок типа xml, что позволяет повысить производительность запросов к XML-данным. Первичный XML-индекс - это сжатое представление все ветвей XML-документа, которые процессор обработки запросов использует для быстрого нахождения ветвей в документе. После того как первичный XML-индекс создан, можно создать вторичный XML-индекс, который поможет повысить производительность при выполнении ряда специфических запросов. В следующем примере показано, как создать первичный XML-индекс и вторичный XML-индекс типа PATH, который позволит улучшить производительность при выполнении XPath_ запросов к данному XML-документу.
CREATE PRIMARY XML INDEX idx_XML-Notes
 ON SalesOrders (Notes)
 GO
CREATE XML INDEX idx_XML-Path_Notes
 ON SalesOrders (Notes)
 USING XML INDEX idx_XML-Notes
 FOR PATH
 GO

Функциональность, реализованная в SQL Server 2000 и 2005, была расширена в SQL Server 2008. К ключевым расширениям в области поддержки работы с XML в SQL Server 2008 можно отнести улучшенные возможности проверки данных на соответствие схеме, расширенную поддержку XQuery и расширенную функциональность при вставке XML-данных средствами DML (Data Manipulation Language).

Расширения XSD
Проверка данных на соответствие схеме позволяет убедиться в том, что XML-документ, хранимый в SQL Server, соответствует определенному стандарту и заданным на уровне схемы бизнес_правилам. На уровне схемы задаются допустимые в XML-документе элементы и атрибуты, что позволяет убедиться в том, что XML-документ содержит требуемые данные в рамках предопределенной структуры.
В SQL Server 2005 появилась поддержка проверки XML-данных на основе коллекций XSD_ схем. Подход заключается в том, что вы создаете коллекцию схем, которая содержит схемы с правилами для XML-данных, используя команду CREATE XML SCHEMA COLLECTION, а затем ссылаетесь на имя коллекции при задании колонки или переменной типа xml, которая должна соответствовать правилам, описанным на уровне схемы.
SQL Server выполняет проверку вводимых или обновляемых данных на соответствие указанной коллекции схем. В SQL Server 2005 реализовано подмножество полной спецификации XML Schema и поддерживаются ключевые сценарии проверки вводимых XML-данных.
В SQL Server 2008 поддержка XSD_схем расширена за счет введения дополнительных возможностей, к которым относятся поддержка проверки на уровне any (т. н. lax validation), полная поддержка проверки на уровне dateTime, time и date, включая сохранение информации о часовых поясах и улучшенная поддержка типов union и list.
Поддержка проверки на уровне шаблонов реализована на уровне конструкций any, anyAttribute и anyType. Например, следующая схема:
<xs:complexType name="Order" mixed="true">
 <xs:sequence>
  <xs:element name="CustomerName"/>
  <xs:element name="OrderTotal"/>
  <xs:any namespace="##other" processContents="skip"  minOccurs="0" maxOccurs="unbounded"/>
 </xs:sequence>
</xs:complexType>
 задает XML-элемент с именем Order, который должен содержать вложенные элементы с именами CustomerName и OrderTotal. Помимо этого, элемент может содержать неограниченное число других элементов, относящихся к пространствам имен, отличным от того, в котором определен тип Order.
Следующий XML-документ содержит экземпляр элемента Order, соответствующий описанию схемы. Обратите внимание на то, что в документе также содержится элемент shp:Delivery, который не описан в схеме.
<Order>
<CustomerName>Graeme Malcolm</CustomerName>
<OrderTotal>299.99</OrderTotal>
<shp:Delivery>Express</shp:Delivery>
</Order>
</Invoice>

Проверка на соответствие шаблону зависит от атрибута processContents для секции схемы, в которой описываются шаблоны. В SQL Server 2005 схемы могут содержать значения атрибута processContents - skip и strict для объявлений any и anyAttribute. В предыдущем примере атрибут processContents для шаблона имел значение skip - таким образом, содержимое данного элемента не проверялось. Даже если в схеме описан элемент shp:Delivery, он не будет проверяться до тех пор, пока в описании шаблона для элемента Order значение атрибута processContents не будет установлено в strict.

В SQL Server 2008 добавлено третье возможное значение атрибута processContents - lax, которое позволяет указать на то, что все элементы, описанные в схеме, должны быть включены в проверку, а элементы, не содержащиеся в схеме, могут быть проигнорированы. Таким образом, если в предыдущем примере присвоить атрибуту processContents для шаблона значение lax, и добавить в схему описание элемента shp:Delivery, этот элемент будет включен в проверку. Но так как элемент shp:Delivery не описан в схеме, он не будет включен в проверку. Помимо этого, спецификация XML Schema определяет, что атрибут anyType автоматически подлежит проверке согласно описанным выше правилам. В SQL Server 2005 lax-проверка не поддерживалась - по умолчанию выполнялась проверка на уровне strict.
Для задания данных, описывающих дату и время, в XML-схемах используется тип данных dateTime. Дата и время задаются в следующем формате: 2007 12 01T21:11:20:000Z, который представляет собой 1-е декабря 2007 года, 11 часов 20 минут по Гринвичу - UTC (000Z). Другие часовые пояса в следующем формате: 000+3:00, например, описывает московское время. Спецификация XML Schema задает компонент часового пояса типов данных dateTime, date и time как опциональный. Тем не менее, в SQL Server 2005 требовалось указание часового пояса при задании данных типа date_Time, date и time.
Помимо этого, в SQL Server 2005 данные о часовом поясе не сохранялись, а приводились к UTC - например, значение 2007_12_25T06:00:00:000_8:00 превращалось в 2007_12_25T14:00:00:000Z. В SQL Server 2008 эти ограничения удалены - при задании даты и времени можно не указывать часовой пояс, но если он указан, данные сохраняются корректно.
Разработчики могут использовать XML-схемы для задания типов данных для XML-данных так, что эти данные могут содержать набор значений, присваиваемых элементам и атрибутам. Например, можно определить тип sizeListType, который ограничивает список возможных значений, присваиваемых элементу AvaliableSizes до S, M и L. В SQL Server 2005 поддерживаются схемы, содержащие простые определения типов и соответствующие ограничения. Например, можно использовать тип list для задания возможных размеров, как показано в следующем примере:
<xs:simpleType name="sizeListType">
 <xs:list>
 <xs:simpleType>
  <xs:restriction base="xs:string">
   <xs:enumeration value="S"/>
   <xs:enumeration value="M"/>
   <xs:enumeration value="L"/>
  </xs:restriction>
 </xs:simpleType>
 </xs:list>
</xs:simpleType>

Такое описание схемы позволяет создать элемент, который содержит все возможные размеры в виде списка значений, разделенных пробелами - это показано в следующем примере:
 
<AvailableSizes>S M L</AvailableSizes>
Продолжение в части 2.

 

 

Сортировать по: Дата публикации | Последние | Самый полезный
Комментарии
  • Nice article!

Страница 1 из 1 (элементов: 1)