Использование режима AUTO с FOR XML

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

Как описано в FOR XML (SQL Server), режим AUTO возвращает результаты запроса в виде вложенных XML-элементов. Это не обеспечивает большого контроля над формой XML, созданной из результата запроса. Запросы в режиме AUTO полезны, если необходимо формировать простые иерархии. При этом использование режима EXPLICIT совместно с предложением FOR XML и использование режима PATH совместно с FOR XML дают больше контроля и гибкости при выборе формы XML из результатов запроса.

Каждая таблица в предложении FROM, из которой по крайней мере один столбец присутствует в предложении SELECT, представляется как элемент XML. Столбцы, перечисляемые в предложении SELECT, сопоставляются атрибутам или подчиненным элементам, если в предложении FOR XML указан необязательный аргумент ELEMENTS.

XML-иерархия (порядок вложенности элементов) в результирующих XML-данных основана на порядке таблиц, определяемых столбцами, которые указаны в предложении SELECT. Поэтому важен порядок, в котором в предложении SELECT указываются имена столбцов. Первая, самая левая идентифицируемая таблица образует верхний элемент в результирующем XML-документе. Вторая слева таблица, идентифицируемая столбцами в инструкции SELECT, образует элемент, подчиненный верхнему элементу и т. д.

Если столбец, имя которого указывается в предложении SELECT, принадлежит таблице, уже идентифицируемой столбцом, заданным до этого в предложении SELECT, вместо открытия нового уровня иерархии этот столбец добавляется как атрибут уже созданного элемента. Если указан аргумент ELEMENTS, столбец добавляется как атрибут.

В качестве примера рассмотрим выполнение следующего запроса:

SELECT Cust.CustomerID,
       OrderHeader.CustomerID,
       OrderHeader.SalesOrderID,
       OrderHeader.Status,
       Cust.CustomerType
FROM Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
WHERE Cust.CustomerID = OrderHeader.CustomerID
ORDER BY Cust.CustomerID
FOR XML AUTO;

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

<Cust CustomerID="1" CustomerType="S">
  <OrderHeader CustomerID="1" SalesOrderID="43860" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="44501" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="45283" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="46042" Status="5" />
</Cust>
...

В предложении SELECT следует отметить следующее.

  • Идентификатор CustomerID ссылается на таблицу «Cust». <Cust> Поэтому создается элемент, а CustomerID добавляется в качестве его атрибута.

  • Далее три столбца, OrderHeader.CustomerID, OrderHeader.SaleOrderID и OrderHeader.Status ссылаются на таблицу OrderHeader. <OrderHeader> Поэтому элемент добавляется в качестве подэлемента <Cust> элемента, а три столбца добавляются в качестве атрибутов<OrderHeader>.

  • Далее, столбец Cust.CustomerType вновь ссылается на таблицу «Cust», которая уже была идентифицирована столбцом Cust.CustomerID. Поэтому никакого нового элемента не создается. Вместо этого атрибут CustomerType добавляется в <Cust> созданный ранее элемент.

  • Запрос задает псевдонимы для имен таблиц. Эти псевдонимы представляются как имена соответствующих элементов.

  • Для группирования всех дочерних элементов одного родителя необходимо предложение ORDER BY.

Следующий запрос аналогичен предыдущему, за исключением того, что предложение SELECT задает столбцы в таблице OrderHeader перед столбцами в таблице «Cust». Поэтому сначала создается элемент <OrderHeader> , а затем в него добавляется дочерний <Cust> элемент.

select OrderHeader.CustomerID,
       OrderHeader.SalesOrderID,
       OrderHeader.Status,
       Cust.CustomerID,
       Cust.CustomerType
from Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
where Cust.CustomerID = OrderHeader.CustomerID
for xml auto;

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

<OrderHeader CustomerID="1" SalesOrderID="43860" Status="5">
  <Cust CustomerID="1" CustomerType="S" />
</OrderHeader>
...

Если в предложение FOR XML добавляется аргумент ELEMENTS, происходит возврат кода XML, основанного на элементах.

SELECT Cust.CustomerID,
       OrderHeader.CustomerID,
       OrderHeader.SalesOrderID,
       OrderHeader.Status,
       Cust.CustomerType
FROM Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
WHERE Cust.CustomerID = OrderHeader.CustomerID
ORDER BY Cust.CustomerID
FOR XML AUTO, ELEMENTS

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

<Cust>
  <CustomerID>1</CustomerID>
  <CustomerType>S</CustomerType>
  <OrderHeader>
    <CustomerID>1</CustomerID>
    <SalesOrderID>43860</SalesOrderID>
    <Status>5</Status>
  </OrderHeader>
   ...
</Cust>
...

В этом запросе значения CustomerID сравниваются между одной строкой и следующей при создании <элементов Cust> , так как CustomerID является первичным ключом таблицы. Если CustomerID не определен как первичный ключ для таблицы, все значения столбцов (CustomerID, CustomerType в этом запросе) сравниваются с одной строкой с следующей. Если значения отличаются, в XML добавляется новый <элемент Cust> .

Если сравниваемые столбцы имеют тип данных text, ntext, imageили xml, при сравнении значений соответствующих строк использование FOR XML предполагает, что значения различаются, поэтому они не сравниваются, даже если могут быть одинаковыми. Это связано с тем, что сравнение больших объектов не поддерживается. Элементы добавляются в результат для каждой выбранной строки. Сравниваются столбцы (n)varchar(max) и varbinary(max).

Если столбец в предложении SELECT не может быть связан с любой из таблиц, определенных в предложении FROM, как в случае статистического столбца или вычисляемого столбца, столбец добавляется в XML-документ в самом глубоком уровне вложения, если он обнаружен в списке. Если такой столбец является первым столбцом в предложении SELECT, столбец добавляется к верхнему элементу.

Если в предложении SELECT задается символ-шаблон «*», вложенность определяется таким же образом, как это описано выше, на основании порядка, в котором строки возвращаются механизмом запроса.

Следующие шаги

В следующих статьях содержатся дополнительные сведения о режиме AUTO:

См. также