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

Применяется к:SQL ServerAzure SQL DatabaseAzure, управляемому экземпляру SQL Azure

Поддержка SQL Server для типа данных XML (Transact-SQL) позволяет при необходимости запрашивать результат XML-запроса FOR XML, указав директиву TYPE. Это позволяет обрабатывать результат запроса 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 . Поскольку в запросе TYPE указана директива FOR XML, результат возвращается в виде типа xml .

USE AdventureWorks2022;
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 присваивается переменной типа xml @x. Запрос извлекает информацию о контактах, например BusinessEntityID, FirstName, LastName, а также дополнительные телефонные номера из столбца AdditionalContactInfoxmlTYPE. Поскольку в предложении FOR XML указана директива TYPE , результат возвращается в виде типа xml и присваивается переменной.

USE AdventureWorks2022;
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() Method (xml Data Type).

USE AdventureWorks2022;
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 AdventureWorks2022;
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

См. также