Работа с XML в SQL Server (часть 2) (ru-RU)

Продолжение статьи про работу с XML в SQL Server

Предположим, что нам нужно предоставить два различных способа описания возможных размеров продукта. Предположим, например, что одежда имеет размеры 46, 48 и 50, но также может описываться как S, M и L. Для поддержки такой возможности в SQL Server 2008 введен тип union, который содержит несколько типов list, которые могут объединяться в единый тип, описывающий возможные значения для определенного типа.
В приведенном ниже примере показано, как создать XML-схему, содержащую тип productSizeType, для которого допустимыми значениями будут числовые значения (46, 48, 50) и символьные значения (S, M L).

CREATE XML SCHEMA COLLECTION CatalogSizeSchema AS
N'<?xml version="1.0" encoding="UTF_16"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="productSizeType">
<xs:union>
<xs:simpleType>
<xs:list>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:enumeration value="46"/>
<xs:enumeration value="48"/>
<xs:enumeration value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:list>
</xs:simpleType>
<xs:simpleType>
<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>
</xs:union>
</xs:simpleType>
</xs:schema>'

При таком описании схемы элементы, базирующиеся на типе productSizeType, могут содержать значения из любого списка - в следующем примере показано, что оба элемента будут соответствовать правилам, заданным в схеме.

<Catalog>
 <Product>
  <ProductName>Polo Shirt</ProductName>
  <AvailableSizes>46 48</AvailableSizes>
 </Product>
 <Product>
  <ProductName>Long_Sleeve Shirt</ProductName>
  <AvailableSizes>S M L</AvailableSizes>
 </Product>
</Catalog>

Точно также в SQL Server 2008 поддерживаются задания в схеме типов list, содержащих внутри себя типы union.

Расширения XQuery
Как мы отметили выше, поддержка типа данных xml впервые появилась в SQL Server 2005. Эта поддержка, в частности, включала предоставление разработчикам ряда методов для манипуляции XML-данными, хранимыми в переменных или колонках соответствующего типа. Большинство операций над XML-данными можно выполнить, используя синтаксис XQuery, который поддерживает как навигацию по данным, так и манипуляции с этими данными.
Синтаксис XQuery, поддерживаемый в SQL Server 2005, включает такие конструкции, как for, where, order by и return, которые вместе называются FLWOR_выражениями и могут использоваться для перебора ветвей XML-документа и возврата найденных значений. В SQL Server 2008 добавлена конструкция let, позволяющая присваивать значения переменным в выражениях XQuery - пример использования данной конструкции показан ниже.

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(
'<Orders>
{
for $invoice in /Invoices/Invoice
let $count :=count($invoice/Items/Item)
order by $count
return
<Order>
{$invoice/Customer}
<ItemCount>{$count}</ItemCount>
</Order>
}
</Orders>')

В результате выполнения данного кода будет создан следующий XML-документ:

<Orders>
 <Order>
  <Customer>Margaret Smith</Customer>
  <ItemCount>1</ItemCount>
 </Order>
 <Order>
  <Customer>Kim Abercrombie</Customer>
  <ItemCount>3</ItemCount>
 </Order>
</Orders>

Обратите внимание на то, что в SQL Server 2008 не поддерживается присваивание значений элементам, создаваемым на лету.

Расширения XML DML
Помимо рассмотренной выше поддержки выражений XQuery для выполнения манипуляций над XML-данными, тип данных xml поддерживает такие XML DML команды, как insert, replace value of и delete - для этого используется метод modify. Эти команды могут использоваться для манипуляции XML-данными, хранимыми в переменных или в колонках типа xml. В SQL Server 2008 также поддерживается использование переменных типа xml при выполнении команды insert для вставки XML-данных в существующую XML-структуру. Например, предположим, что переменная @productList типа xml содержит следующий документ:

<Products>
 <Bike>Mountain Bike</Bike>
 <Bike>Road Bike</Bike>
</Products>

Мы можем использовать следующий код для вставки нового продукта в уже существующий документ:

DECLARE @newBike xml
SET @newBike = '<Bike>Racing Bike</Bike>'
@productList.modify
('insert sql:variable("@newBike") as last into (/Products)[1]')

После выполнения этого кода переменная @productList будет содержать следующий XML-документ:

<Products>
 <Bike>Mountain Bike</Bike>
 <Bike>Road Bike</Bike>
 <Bike>Racing Bike</Bike>
</Products>