Поддержка 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-потока. Пример использования данной функциональности показан ниже. Следующий запрос:
Начнем с того, что кратко вспомним ключевые возможности по работе с 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. Пример использования данной функциональности показан ниже. Следующий запрос:
В 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
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-индекс, который поможет повысить производительность при выполнении ряда специфических запросо:bold;">Customer
>
</
CustomerList
>
в. В следующем примере показано, как создать первичный 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
>
<
xs:element
name
=
"CustomerName"
/>
<
xs:element
name
=
"OrderTotal"
/>
namespace
=
"##other"
processContents
=
"skip"
minOccurs
=
"0"
maxOccurs
=
"unbounded"
/>
</
xs:sequence
>
</
xs:complexType
>
задает XML-элемент с именем Order, который должен содержать вложенные элементы с именами CustomerName и OrderTotal. Помимо этого, элемент может содержать неограниченное число других элементов,
относящихся к пространствам имен, отличным от того, в котором определен тип Order.
Следующий XML-документ содержит экземпляр элемента Order, соответствующий описанию схемы. Обратите внимание на то, что в документе также содержится элемент shp:Delivery, который не описан в схеме.
Следующий XML-документ содержит экземпляр элемента Order, соответствующий описанию схемы. Обратите внимание на то, что в документе также содержится элемент shp:Delivery, который не описан в схеме.
<
Invoice
xmlns
=
"http://adventure_works.com/order"
xmlns:shp
=
"http://adventure_works.com/shipping"
>
<
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
>