Директива TYPE в запросах FOR XML

В SQL Server 2000 результат запроса FOR XML всегда возвращается прямо клиенту в текстовой форме. Благодаря поддержке типа данных XML в SQL Server 2005 с помощью директивы TYPE можно запросить возвращение результата запроса FOR XML в виде типа данных xml. Это позволяет обрабатывать результат запроса FOR XML на сервере. Например, к нему можно применить инструкции на языке XQuery, присвоить его результат переменной типа xml или написать вложенные запросы FOR XML.

ms190025.note(ru-ru,SQL.90).gifПримечание.
SQL Server возвращает клиенту XML-данные экземпляра, являющиеся результатом различных серверных конструкций, таких как запросы FOR XML, использующие директиву TYPE или тип данных xml для возвращения значений XML-данных экземпляра из столбцов таблицы и выходных параметров, возвращенных SQL-запросом. В коде клиентского приложения поставщик ADO.NET запрашивает эти XML-данные для отправки с сервера в двоичной кодировке. Однако при использовании предложения FOR XML без директивы TYPE XML-данные возвращаются как данные строкового типа. Как бы то ни было, поставщик клиента имеет возможность обрабатывать XML-данные в любом из форматов.

Примеры

В следующих примерах показано использование запроса FOR XML.

А. Получение результатов запроса FOR XML в виде XML-данных

Следующий запрос используется для получения контактных сведений о клиенте из таблицы Contacts. Поскольку в запросе FOR XML указана директива TYPE, результат возвращается в виде xml-данных.

SELECT ContactID, FirstName, LastName, Phone
FROM Person.Contact
ORDER BY ContactID
FOR XML AUTO, TYPE

Частичный результат:

<Contact ContactID="1" FirstName="Syed" LastName="Abbas" 
         Phone="398-555-0132"/>
<Contact ContactID="2" FirstName="Catherine" LastName="Abel" 
         Phone="747-555-0171"/>
...

Б. Присвоение результатов запроса FOR XML переменной типа xml

В следующем примере результат запроса FOR XML присваивается переменной типа xml, @x. Данный запрос извлекает контактные сведения, такие как ContactID, FirstName, LastName и дополнительные номера телефонов, из столбца AdditionalContactInfo типа xml. Поскольку в предложении FOR XML указана директива TYPE, результат возвращается в виде типа xml и присваивается переменной.

DECLARE @x XML
SET @x = (
   SELECT ContactID, 
          FirstName, 
          LastName, 
          AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
              //act:telephoneNumber/act:number') as MorePhoneNumbers
   FROM Person.Contact
   FOR XML AUTO, TYPE)
SELECT @x
GO

В. Запрос к результатам запроса FOR XML

Запросы FOR XML возвращают XML-данные. Таким образом, можно применить методы типа xml, например query() и value(), к XML-данным, возвращенным запросами FOR XML.

В следующем запросе метод query() для типа данных xml используется с целью запроса к результатам запроса FOR XML. Дополнительные сведения см. в разделе query() (тип данных xml).

SELECT (SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
 //act:telephoneNumber/act:number
') as PhoneNumbers
FROM Person.Contact
FOR XML AUTO, TYPE).query('/Person.Contact[1]')

Внутренний запрос SELECT ... FOR XML возвращает результат типа xml, к которому внешний запрос SELECT применяет метод query() для типа xml. Обратите внимание на указанную директиву TYPE.

Результат:

<Person.Contact ContactID="1" FirstName="Gustavo" LastName="Achong">
  <PhoneNumbers>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">111-111-1111</act:number>
    <act:number xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">112-111-1111</act:number>
  </PhoneNumbers>
</Person.Contact>

В следующем запросе метод value() для типа данных xml используется с целью получения значения из результата XML, возвращенного запросом SELECT...FOR XML. Дополнительные сведения см. в разделе Метод value() (тип данных xml).

declare @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";

   //act:telephoneNumber/act:number
   ') as PhoneNumbers
   FROM Person.Contact Contact
   FOR XML AUTO, TYPE).value('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@ContactID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
select @FirstPhoneFromAdditionalContactInfo

Выражение пути XQuery в методе value() извлекает из контактных сведений о заказчике первый номер телефона с идентификатором ContactID, равным 1.

ms190025.note(ru-ru,SQL.90).gifПримечание.
Если директива TYPE не указана, результат запроса FOR XML возвращается в виде данных типа nvarchar(max).

Г. Использование результатов запроса FOR XML в инструкциях INSERT, UPDATE и DELETE (Transact-SQL DML)

В следующем примере показано использование запросов FOR XML в инструкциях языка DML. В данном примере запрос FOR XML возвращает экземпляр типа xml. Инструкция INSERT вставляет этот экземпляр XML в таблицу.

CREATE TABLE T1(intCol int, XmlCol xml)
go
INSERT INTO T1 
VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')
go

CREATE TABLE T2(XmlCol xml)
go
INSERT INTO T2(XmlCol) 
SELECT (SELECT XmlCol.query('/Root') 
        FROM T1 
        FOR XML AUTO,TYPE) 
go