Директива TYPE в запросах FOR XML
В SQL Server 2000 результат запроса FOR XML всегда возвращается прямо клиенту в текстовой форме. Благодаря поддержке типа данных XML в SQL Server 2005 с помощью директивы 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.
А. Получение результатов запроса 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