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


Директива 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-данных.

USE AdventureWorks2008R2;
Go
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
ORDER BY BusinessEntityID
FOR XML AUTO, TYPE;

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

<Person.Person BusinessEntityID="1" FirstName="Ken" LastName="Sбnchez"/>

<Person.Person BusinessEntityID="2" FirstName="Terri" LastName="Duffy"/>

...

Назначение результатов запроса FOR XML переменной типа xml

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

USE AdventureWorks2008R2;
GO
DECLARE @x xml;
SET @x = (
   SELECT BusinessEntityID, 
          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.Person
   FOR XML AUTO, TYPE);
SELECT @x;
GO

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

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

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

USE AdventureWorks2008R2;
GO
SELECT (SELECT BusinessEntityID, 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.Person
FOR XML AUTO, TYPE).query('/Person.Person[1]');

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

Результат:

<Person.Person BusinessEntityID="1" FirstName="Ken" LastName="Sбnchez">

<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.Person>

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

USE AdventureWorks2008R2;
GO
DECLARE @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT BusinessEntityID, 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.Person Contact
   FOR XML AUTO, TYPE).value('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@BusinessEntityID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
SELECT @FirstPhoneFromAdditionalContactInfo;

Выражение пути XQuery в методе value() извлекает из контактных сведений первый номер телефона заказчика с идентификатором BusinessEntityID, равным 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