Поделиться через


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

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

ПримечаниеПримечание

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

Примеры

В следующих примерах показано использование директивы TYPE в запросах 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.

ПримечаниеПримечание

Если директива 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