Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В SQL Server 2000 предложение FOR XML можно указать только на верхнем уровне запроса SELECT. Результирующий XML в основном возвращается клиенту для дальнейшей обработки. В SQL Server 2005 с появлением типа данных xml и директивы TYPE в запросах FOR XML текст в формате XML, возвращаемый запросами FOR XML, может быть дополнительно обработан на сервере.
Результат запроса FOR XML можно присвоить переменной типа xml или воспользоваться языком XQuery, чтобы выполнить к нему запрос, после чего и присвоить полученный результат переменной типа xml для дополнительной обработки.
DECLARE @x xml SET @x=(SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID=122 or ProductModelID=119 FOR XML RAW, TYPE) SELECT @x -- Result --<row ProductModelID="122" Name="All-Purpose Bike Stand" /> --<row ProductModelID="119" Name="Bike Wash" />XML-данные, возвращаемые в переменной
@x, можно дополнительно обработать с применением методов типа данных xml. Например, можно получить значение атрибутаProductModelIDс помощью метода value() (тип данных xml).DECLARE @i int SET @i = (SELECT @x.value('/row[1]/@ProductModelID[1]', 'int')) SELECT @iВ следующем примере результат запроса
FOR XMLвозвращается в виде типа данных xml, так как в выраженииFOR XMLуказана директиваTYPE.SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID=119 or ProductModelID=122 FOR XML RAW, TYPE,ROOT('myRoot')Результат:
<myRoot> <row ProductModelID="122" Name="All-Purpose Bike Stand" /> <row ProductModelID="119" Name="Bike Wash" /> </myRoot>Поскольку результат имеет тип xml, непосредственно к нему можно применить один из методов типа данных xml, как показано в следующем запросе. В запросе метод query() (тип данных xml) используется для получения первого дочернего элемента <
row> элемента <myRoot>.SELECT (SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID=119 or ProductModelID=122 FOR XML RAW, TYPE,ROOT('myRoot')).query('/myRoot[1]/row[1]')Результат:
<row ProductModelID="122" Name="All-Purpose Bike Stand" />Кроме этого, можно создавать вложенные запросы
FOR XML, где результат внутреннего запроса возвращает внешнему запросу данные типа xml. Например:SELECT Col1, Col2, ( SELECT Col3, Col4 FROM T2 WHERE T2.Col = T1.Col ... FOR XML AUTO, TYPE ) FROM T1 WHERE ... FOR XML AUTO, TYPEВ предыдущем запросе обратите внимание на следующие моменты:
- XML-данные, сформированные внутренним запросом
FOR XML, добавляются к XML-результату внешнего запросаFOR XML. - Во внутреннем запросе указана директива
TYPE. Таким образом, возвращаемые внутренним запросом XML-данные имеют тип xml. Если директива TYPE не указана, внутренний запросFOR XMLвозвращает результат типа nvarchar(max) и XML-данные преобразуются в сущности.
Вложенные запросы FOR XML дают больший контроль над форматом результирующих XML-данных.
В SQL Server 2000 запросы режимов RAW и AUTO по умолчанию формируют атрибутивную модель XML-данных. Например:
SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID=122 or ProductModelID=119 FOR XML RAWРезультат является атрибутивным:
<row ProductModelID="122" Name="All-Purpose Bike Stand" /> <row ProductModelID="119" Name="Bike Wash" />Указав директиву
ELEMENTS, можно получить все XML-данные в элементной форме. Например:SELECT ProductModelID, Name FROM Production.ProductModel WHERE ProductModelID=122 or ProductModelID=119 FOR XML RAW, ELEMENTSРезультат является элементным:
<row> <ProductModelID>122</ProductModelID> <Name>All-Purpose Bike Stand</Name> </row> <row> <ProductModelID>119</ProductModelID> <Name>Bike Wash</Name> </row>SQL Server 2005 позволяет для вложенных запросов FOR XML конструировать XML-данные, сочетающие в себе атрибутивную и элементную модели.
В SQL Server 2000 узлы с общим родителем можно создавать только с помощью запросов в режиме EXPLICIT. Однако пользоваться этим способом не всегда удобно. В SQL Server 2005 с помощью вложенных запросов FOR XML в режиме AUTO можно формировать XML-иерархии, содержащие узлы с общим родителем.
Независимо от используемого режима вложенные запросы FOR XML предоставляют больший контроль при описании формата результирующих XML-данных. Их можно использовать вместо запросов в режиме EXPLICIT.
- XML-данные, сформированные внутренним запросом
Примеры
А. Сравнение запроса FOR XML с вложенным запросом FOR XML
Следующий запрос SELECT позволяет получить сведения о категории и подкатегории продукта в базе данных AdventureWorks. В запросе нет вложенных запросов FOR XML.
SELECT ProductCategory.ProductCategoryID,
ProductCategory.Name as CategoryName,
ProductSubCategory.ProductSubCategoryID,
ProductSubCategory.Name
FROM Production.ProductCategory, Production.ProductSubCategory
WHERE ProductCategory.ProductCategoryID = ProductSubCategory.ProductCategoryID
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE
GO
Промежуточный результат:
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory ProductSubCategoryID="1" Name="Mountain Bike"/>
<ProductSubCategory ProductSubCategoryID="2" Name="Road Bike"/>
<ProductSubCategory ProductSubCategoryID="3" Name="Touring Bike"/>
</ProductCategory>
...
Если в запросе указана директива ELEMENTS, то результат будет представлен в элементной форме, как показано в следующем фрагменте результата:
<ProductCategory>
<ProductCategoryID>1</ProductCategoryID>
<CategoryName>Bike</CategoryName>
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<Name>Mountain Bike</Name>
</ProductSubCategory>
<ProductSubCategory>
...
</ProductSubCategory>
</ProductCategory>
Предположим, что нужно создать иерархию XML-данных, которая сочетает атрибутивную и элементную модели, как показано в следующем фрагменте:
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
<ProductSubCategory>
...
<ProductSubCategory>
...
</ProductCategory>
В этом фрагменте такие сведения о категории продукта, как идентификатор категории и имя категории, являются атрибутами. Однако сведения о подкатегории представлены с использованием элементов. Для конструирования элемента <ProductCategory> можно написать запрос FOR XML, как показано ниже:
SELECT ProductCategoryID, Name as CategoryName
FROM Production.ProductCategory ProdCat
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE
Результат:
< ProdCat ProductCategoryID="1" CategoryName="Bikes" />
< ProdCat ProductCategoryID="2" CategoryName="Components" />
< ProdCat ProductCategoryID="3" CategoryName="Clothing" />
< ProdCat ProductCategoryID="4" CategoryName="Accessories" />
Для создания необходимых вложенных элементов <ProductSubCategory> необходимо после этого добавить вложенный запрос FOR XML, как показано ниже:
SELECT ProductCategoryID, Name as CategoryName,
(SELECT ProductSubCategoryID, Name SubCategoryName
FROM Production.ProductSubCategory
WHERE ProductSubCategory.ProductCategoryID =
ProductCategory.ProductCategoryID
FOR XML AUTO, TYPE, ELEMENTS
)
FROM Production.ProductCategory
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE
Для предыдущего запроса необходимо отметить следующее:
- Внутренний запрос
FOR XMLполучает сведения о подкатегории продукта. ДирективаELEMENTSдобавляется во внутренний запросFOR XML, создавая элементный XML, который добавляется к XML-данным, создаваемым внешним запросом. По умолчанию внешний запрос создает XML-данные по атрибутивной модели. - Во внутреннем запросе указана директива
TYPE, поэтому результат имеет тип xml. Если директиваTYPEне указана, то возвращается результат типа nvarchar(max) и XML-данные возвращаются как сущности. - Внешний запрос также содержит директиву
TYPE, поэтому результат запроса возвращается клиенту как тип xml.
Промежуточный результат:
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
<ProductSubCategory>
...
<ProductSubCategory>
...
</ProductCategory>
Следующий запрос представляет собой расширение предыдущего запроса. Он показывает полную иерархию продуктов в базе данных AdventureWorks. Это включает следующее.
- Категории продукции
- Подкатегории продукции в каждой категории
- Модели продуктов в каждой подкатегории
- Продукты в каждой модели
Следующий пример может быть полезен для понимания базы данных AdventureWorks:
SELECT ProductCategoryID, Name as CategoryName,
(SELECT ProductSubCategoryID, Name SubCategoryName,
(SELECT ProductModel.ProductModelID,
ProductModel.Name as ModelName,
(SELECT ProductID, Name as ProductName, Color
FROM Production.Product
WHERE Product.ProductModelID =
ProductModel.ProductModelID
FOR XML AUTO, TYPE)
FROM (SELECT distinct ProductModel.ProductModelID,
ProductModel.Name
FROM Production.ProductModel,
Production.Product
WHERE ProductModel.ProductModelID =
Product.ProductModelID
AND Product.ProductSubCategoryID =
ProductSubCategory.ProductSubCategoryID)
ProductModel
FOR XML AUTO, type
)
FROM Production.ProductSubCategory
WHERE ProductSubCategory.ProductCategoryID =
ProductCategory.ProductCategoryID
FOR XML AUTO, TYPE, ELEMENTS
)
FROM Production.ProductCategory
ORDER BY ProductCategoryID
FOR XML AUTO, TYPE
Промежуточный результат:
<Production.ProductCategory ProductCategoryID="1" CategoryName="Bikes">
<Production.ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bikes</SubCategoryName>
<ProductModel ProductModelID="19" ModelName="Mountain-100">
<Production.Product ProductID="771"
ProductName="Mountain-100 Silver, 38" Color="Silver" />
<Production.Product ProductID="772"
ProductName="Mountain-100 Silver, 42" Color="Silver" />
<Production.Product ProductID="773"
ProductName="Mountain-100 Silver, 44" Color="Silver" />
…
</ProductModel>
…
Если удалить директиву ELEMENTS из вложенного запроса FOR XML, который создает подкатегории продуктов, то весь результат будет создан по атрибутивной модели. Этот запрос можно составить без вложений. Добавление директивы ELEMENTS приводит к созданию XML-документа как по атрибутивной, так и по элементной модели. Этот результат нельзя сформировать с помощью одноуровневого запроса FOR XML.
Б. Создание элементов с общим родителем с использованием вложенного запроса в режиме AUTO
В следующем примере показано, как создавать элементы с общим родителем при помощи вложенного запроса в режиме AUTO. Единственный способ создать такой XML — использовать режим EXPLICIT. Однако воспользоваться этим способом не всегда удобно.
Этот запрос создает XML, который предоставляет сведения о заказах на продажу. Это включает следующее:
- В базе данных AdventureWorks заголовки данных о заказах продаж
SalesOrderID,SalesPersonIDиOrderDateхранятся в таблицеSalesOrderHeader. - Дополнительные сведения о заказе на продажу. Она включает один или несколько заказанных продуктов, цену за штуку и заказанное количество. Эти сведения хранятся в таблице
SalesOrderDetail. - Сведения о менеджере по продажам. Сведения о менеджере по продажам, принявшем заказ. В таблице
SalesPersonхранятся идентификаторыSalesPersonID. Чтобы найти имя менеджера по продажам, в этом запросе данную таблицу необходимо присоединить к таблицеEmployee.
Два отдельных запроса SELECT, показанных ниже, создают XML-документ с небольшими различиями в формате данных.
Первый запрос создает XML, в котором <SalesPerson> и <SalesOrderHeader> появляются как потомки общего родителя <SalesOrder>:
SELECT
(SELECT top 2 SalesOrderID, SalesPersonID, CustomerID,
(select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice
from Sales.SalesOrderDetail
WHERE SalesOrderDetail.SalesOrderID =
SalesOrderHeader.SalesOrderID
FOR XML AUTO, TYPE)
FROM Sales.SalesOrderHeader
WHERE SalesOrderHeader.SalesOrderID = SalesOrder.SalesOrderID
for xml auto, type),
(SELECT *
FROM (SELECT SalesPersonID, EmployeeID
FROM Sales.SalesPerson, HumanResources.Employee
WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As
SalesPerson
WHERE SalesPerson.SalesPersonID = SalesOrder.SalesPersonID
FOR XML AUTO, TYPE)
FROM (SELECT SalesOrderHeader.SalesOrderID, SalesOrderHeader.SalesPersonID
FROM Sales.SalesOrderHeader, Sales.SalesPerson
WHERE SalesOrderHeader.SalesPersonID = SalesPerson.SalesPersonID
) as SalesOrder
ORDER BY SalesOrder.SalesOrderID
FOR XML AUTO, TYPE
В предшествующем запросе самая внешняя инструкция SELECT выполняет следующие действия.
- Запрашивает набор строк
SalesOrder, указанный в предложенииFROM. Результат — XML с одним или несколькими элементами <SalesOrder>. - Задает режим
AUTOи директивуTYPE. В режимеAUTOрезультат запроса преобразуется в XML, а директиваTYPEвозвращает результат типа xml. - Содержит две вложенные инструкции
SELECT, разделенные запятой. Первая вложенная инструкцияSELECTполучает сведения о заказе на продажу, заголовок и дополнительные сведения, а вторая инструкцияSELECTполучает сведения о менеджере по продажам.- Инструкция
SELECT, получающаяSalesOrderID,SalesPersonIDиCustomerID, содержит вложенную инструкциюSELECT ... FOR XML(с режимомAUTOи директивойTYPE), возвращающую подробные данные о заказе на продажу.
- Инструкция
Инструкция SELECT, которая получает сведения о менеджере по продажам, запрашивает набор строк SalesPerson, созданный в предложении FROM. Для работы запросов FOR XML необходимо указать имя для анонимного набора строк, создаваемого в предложении FROM. В данном случае указано имя SalesPerson.
Промежуточный результат:
<SalesOrder>
<Sales.SalesOrderHeader SalesOrderID="43659" SalesPersonID="279" CustomerID="676">
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="776" OrderQty="1" UnitPrice="2024.9940" />
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="777" OrderQty="3" UnitPrice="2024.9940" />
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="778" OrderQty="1" UnitPrice="2024.9940" />
</Sales.SalesOrderHeader>
<SalesPerson SalesPersonID="279" EmployeeID="279" />
</SalesOrder>
...
Следующий запрос формирует те же сведения о заказе, за исключением результирующего XML; <SalesPerson> представляет собой элемент, имеющий общего родителя с <SalesOrderDetail>:
<SalesOrder>
<SalesOrderHeader ...>
<SalesOrderDetail .../>
<SalesOrderDetail .../>
...
<SalesPerson .../>
</SalesOrderHeader>
</SalesOrder>
<SalesOrder>
...
</SalesOrder>
Это запрос:
SELECT SalesOrderID, SalesPersonID, CustomerID,
(select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice
from Sales.SalesOrderDetail
WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID
FOR XML AUTO, TYPE),
(SELECT *
FROM (SELECT SalesPersonID, EmployeeID
FROM Sales.SalesPerson, HumanResources.Employee
WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As SalesPerson
WHERE SalesPerson.SalesPersonID = SalesOrderHeader.SalesPersonID
FOR XML AUTO, TYPE)
FROM Sales.SalesOrderHeader
WHERE SalesOrderID=43659 or SalesOrderID=43660
FOR XML AUTO, TYPE
Результат:
<Sales.SalesOrderHeader SalesOrderID="43659" SalesPersonID="279" CustomerID="676">
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="776" OrderQty="1" UnitPrice="2024.9940" />
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="777" OrderQty="3" UnitPrice="2024.9940" />
<Sales.SalesOrderDetail SalesOrderID="43659" ProductID="778" OrderQty="1" UnitPrice="2024.9940" />
<SalesPerson SalesPersonID="279" EmployeeID="279" />
</Sales.SalesOrderHeader>
<Sales.SalesOrderHeader SalesOrderID="43660" SalesPersonID="279" CustomerID="117">
<Sales.SalesOrderDetail SalesOrderID="43660" ProductID="762" OrderQty="1" UnitPrice="419.4589" />
<Sales.SalesOrderDetail SalesOrderID="43660" ProductID="758" OrderQty="1" UnitPrice="874.7940" />
<SalesPerson SalesPersonID="279" EmployeeID="279" />
</Sales.SalesOrderHeader>
Директива TYPE возвращает результат запроса как тип данных xml, поэтому можно выполнять к результирующему XML запросы с использованием различных методов типа данных xml. Дополнительные сведения см. в разделе Методы типа данных xml. В приведенном далее запросе обратите внимание на следующее.
Предшествующий запрос добавлен в предложении
FROM. Результат запроса возвращается в виде таблицы. Следует обратить внимание, что добавлен псевдонимXmlCol.Предложение
SELECTопределяет запрос XQuery кXmlCol, возвращаемому в предложенииFROM. Для указания запроса XQuery применяется метод query() типа данных xml. Дополнительные сведения см. в разделе query() (тип данных xml).SELECT XmlCol.query('<Root> { /* } </Root>') FROM ( SELECT SalesOrderID, SalesPersonID, CustomerID, (select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice from Sales.SalesOrderDetail WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID FOR XML AUTO, TYPE), (SELECT * FROM (SELECT SalesPersonID, EmployeeID FROM Sales.SalesPerson, HumanResources.Employee WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As SalesPerson WHERE SalesPerson.SalesPersonID = SalesOrderHeader.SalesPersonID FOR XML AUTO, TYPE) FROM Sales.SalesOrderHeader WHERE SalesOrderID='43659' or SalesOrderID='43660' FOR XML AUTO, TYPE ) as T(XmlCol)
В. Создание приложения ASPX для получения сведений о заказе на продажу в обозревателе
В этом примере ASPX-приложение выполняет хранимую процедуру и возвращает сведения о заказе на продажу в формате XML. Результат отображается в обозревателе. Инструкция SELECT в хранимой процедуре похожа на инструкцию, приведенную в примере Б, за исключением того, что результирующий XML является элементным.
CREATE PROC GetSalesOrderInfo AS
SELECT
(SELECT top 2 SalesOrderID, SalesPersonID, CustomerID,
(select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice
from Sales.SalesOrderDetail
WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID
FOR XML AUTO, TYPE)
FROM Sales.SalesOrderHeader
WHERE SalesOrderHeader.SalesOrderID = SalesOrder.SalesOrderID
for xml auto, type),
(SELECT *
FROM (SELECT SalesPersonID, EmployeeID
FROM Sales.SalesPerson, HumanResources.Employee
WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As SalesPerson
WHERE SalesPerson.SalesPersonID = SalesOrder.SalesPersonID
FOR XML AUTO, TYPE, ELEMENTS)
FROM (SELECT SalesOrderHeader.SalesOrderID, SalesOrderHeader.SalesPersonID
FROM Sales.SalesOrderHeader, Sales.SalesPerson
WHERE SalesOrderHeader.SalesPersonID = SalesPerson.SalesPersonID
) as SalesOrder
ORDER BY SalesOrder.SalesOrderID
FOR XML AUTO, TYPE
GO
Это приложение ASPX. Оно выполняет хранимую процедуру и возвращает XML в обозреватель:
<%@LANGUAGE=C# Debug=true %>
<%@import Namespace="System.Xml"%>
<%@import namespace="System.Data.SqlClient" %><%
Response.Expires = -1;
Response.ContentType = "text/xml";
%>
<%
using(System.Data.SqlClient.SqlConnection c = new System.Data.SqlClient.SqlConnection("Data Source=server;Database=AdventureWorks;Integrated Security=SSPI;"))
using(System.Data.SqlClient.SqlCommand cmd = c.CreateCommand())
{
cmd.CommandText = "GetSalesOrderInfo";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection.Open();
System.Xml.XmlReader r = cmd.ExecuteXmlReader();
System.Xml.XmlTextWriter w = new System.Xml.XmlTextWriter(Response.Output);
w.WriteStartElement("Root");
r.MoveToContent();
while(! r.EOF)
{
w.WriteNode(r, true);
}
w.WriteEndElement();
w.Flush();
}
%>
Тестирование приложения
- Создайте хранимую процедуру в базе данных AdventureWorks.
- Сохраните приложение .aspx в каталоге c:\inetpub\wwwroot (GetSalesOrderInfo.aspx).
- Выполните приложение (https://server/GetSalesOrderInfo.aspx).
Г. Построение XML, содержащего цены продуктов
В следующем примере к таблице Production.Product выполняется запрос, чтобы получить значения ListPrice и StandardCost указанного продукта. Чтобы сделать пример более информативным, обе цены возвращаются как элемент <Price> и у каждого элемента <Price> имеется атрибут PriceType. Это прогнозируемая форма XML:
<xsd:schema xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes" targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet2" elementFormDefault="qualified">
<xsd:import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="https://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="Production.Product" type="xsd:anyType" />
</xsd:schema>
<Production.Product xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2" ProductID="520">
<Price PriceType="ListPrice">133.34</Price>
<Price PriceType="StandardCost">98.77</Price>
</Production.Product>
Это вложенный запрос FOR XML:
SELECT Product.ProductID,
(SELECT 'ListPrice' as PriceType,
CAST(CAST(ListPrice as NVARCHAR(40)) as XML)
FROM Production.Product Price
WHERE Price.ProductID=Product.ProductID
FOR XML AUTO, TYPE),
(SELECT 'StandardCost' as PriceType,
CAST(CAST(StandardCost as NVARCHAR(40)) as XML)
FROM Production.Product Price
WHERE Price.ProductID=Product.ProductID
FOR XML AUTO, TYPE)
FROM Production.Product
WHERE ProductID=520
for XML AUTO, TYPE, XMLSCHEMA
Из предыдущего запроса стоит отметить следующее.
- Внешняя инструкция SELECT строит элемент <
Product>, который имеет атрибут ProductID и два дочерних элемента <Price>. - Две внутренние инструкции SELECT создают два элемента <
Price>, каждый с атрибутом PriceType, а также XML, который возвращает цену продукта. - Директива XMLSCHEMA во внешней инструкции SELECT создает встроенную XSD-схему, которая описывает форму результирующего XML.
Чтобы сделать запрос более информативным, можно составить запрос FOR XML, а затем подготовить запрос XQuery к результату для переформирования XML, как показано в следующем запросе:
SELECT ProductID,
( SELECT p2.ListPrice, p2.StandardCost
FROM Production.Product p2
WHERE Product.ProductID = p2.ProductID
FOR XML AUTO, ELEMENTS XSINIL, type ).query('
for $p in /p2/*
return
<Price PriceType = "{local-name($p)}">
{ data($p) }
</Price>
')
FROM Production.Product
WHERE ProductID = 520
FOR XML AUTO, TYPE
В предыдущем примере метод query() типа данных xml используется, чтобы запросить XML, возвращаемый внутренним запросом FOR XML, и построить прогнозируемый результат.
Результат:
<Production.Product ProductID="520">
<Price PriceType="ListPrice">133.3400</Price>
<Price PriceType="StandardCost">98.7700</Price>
</Production.Product>