Używanie trybu AUTOMATYCZNEGO z formatem FOR XML
Dotyczy:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Zgodnie z opisem w FOR XML (SQL Server), tryb AUTO zwraca wyniki zapytania jako zagnieżdżone elementy XML. Nie zapewnia to dużej kontroli nad kształtem kodu XML wygenerowanego na podstawie wyniku zapytania. Zapytania trybu AUTOMATYCZNEGO są przydatne, jeśli chcesz wygenerować proste hierarchie. Jednak użycie trybu JAWNEGO z FOR XML i użycie trybu ŚCIEŻKI z FOR XML zapewnia większą kontrolę i elastyczność w określaniu kształtu XML z wyniku zapytania.
Każda tabela w klauzuli FROM, z której co najmniej jedna kolumna jest wymieniona w klauzuli SELECT, jest reprezentowana jako element XML. Kolumny wymienione w klauzuli SELECT są mapowane na atrybuty lub podelementy, jeśli opcjonalna opcja ELEMENTS jest określona w klauzuli FOR XML.
Hierarchia XML, zagnieżdżanie elementów, w wynikowym kodzie XML jest oparte na kolejności tabel zidentyfikowanych przez kolumny określone w klauzuli SELECT. W związku z tym kolejność, w jakiej nazwy kolumn są określone w klauzuli SELECT, jest znacząca. Pierwsza, najbardziej po lewej stronie tabela, która jest identyfikowana, stanowi górny element w wynikowym dokumencie XML. Druga tabela po lewej stronie, zidentyfikowana przez kolumny w instrukcji SELECT, tworzy podelement w górnym elememencie itd.
Jeśli nazwa kolumny wymienionej w klauzuli SELECT pochodzi z tabeli, która jest już identyfikowana przez wcześniej określoną kolumnę w klauzuli SELECT, kolumna zostanie dodana jako atrybut już utworzonego elementu, zamiast otwierać nowy poziom hierarchii. Jeśli zostanie określona opcja ELEMENTS, kolumna zostanie dodana jako atrybut.
Na przykład wykonaj następujące zapytanie:
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;
Jest to wynik częściowy:
<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>
...
Zwróć uwagę na następujące elementy w klauzuli SELECT:
Identyfikator CustomerID odwołuje się do tabeli Cust. W związku z tym tworzony jest element
<Cust>
, a identyfikator CustomerID jest dodawany jako jego atrybut.Następnie trzy kolumny OrderHeader.CustomerID, OrderHeader.SaleOrderID i OrderHeader.Status odwołują się do tabeli OrderHeader. W związku z tym element
<OrderHeader>
jest dodawany jako element podrzędny elementu<Cust>
, a trzy kolumny są dodawane jako atrybuty<OrderHeader>
.Następnie kolumna Cust.CustomerType ponownie odwołuje się do tabeli Cust, która została już zidentyfikowana przez kolumnę Cust.CustomerID. W związku z tym nie jest tworzony żaden nowy element. Zamiast tego atrybut CustomerType jest dodawany do wcześniej utworzonego elementu
<Cust>
.Zapytanie określa aliasy nazw tabel. Te aliasy są wyświetlane jako odpowiednie nazwy elementów.
Funkcja ORDER BY jest wymagana do grupowania wszystkich dzieci pod jednym rodzicem.
To zapytanie jest podobne do poprzedniego, z tą różnicą, że klauzula SELECT określa kolumny w tabeli OrderHeader przed kolumnami w tabeli Cust. W związku z tym najpierw <OrderHeader>
element jest tworzony, a następnie dodawany jest do niego element podrzędny <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;
Jest to wynik częściowy:
<OrderHeader CustomerID="1" SalesOrderID="43860" Status="5">
<Cust CustomerID="1" CustomerType="S" />
</OrderHeader>
...
Jeśli opcja ELEMENTS zostanie dodana w klauzuli FOR XML, zwracany jest kod XML skoncentrowany na elementach.
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
Jest to wynik częściowy:
<Cust>
<CustomerID>1</CustomerID>
<CustomerType>S</CustomerType>
<OrderHeader>
<CustomerID>1</CustomerID>
<SalesOrderID>43860</SalesOrderID>
<Status>5</Status>
</OrderHeader>
...
</Cust>
...
W tym zapytaniu wartości CustomerID są porównywane z jednego wiersza do następnego podczas tworzenia elementów <Cust>, ponieważ CustomerID jest kluczem podstawowym tabeli. Jeśli identyfikator CustomerID nie jest identyfikowany jako klucz podstawowy tabeli, wszystkie wartości kolumn (CustomerID, CustomerType w tym zapytaniu) są porównywane z jednego wiersza do następnego. Jeśli wartości będą się różnić, do kodu XML zostanie dodany nowy element <Cust>.
Podczas porównywania tych wartości kolumn, jeśli którakolwiek z kolumn do porównania jest typu tekst, ntext, obrazlub xml, w trybie FOR XML zakłada się, że wartości są różne i nie są porównywane, mimo że mogą być takie same. Dzieje się tak, ponieważ porównywanie dużych obiektów nie jest obsługiwane. Elementy są dodawane do wyniku dla każdego wybranego wiersza. Porównywane są kolumny (n)varchar(max) i varbinary(max).
Jeśli kolumna w klauzuli SELECT nie może być skojarzona z żadną tabelą zidentyfikowaną w klauzuli FROM, tak jak w przypadku kolumny agregującej lub kolumny obliczeniowej, kolumna jest dodawana w dokumencie XML na najgłębszym poziomie zagnieżdżania w miejscu, w którym występuje na liście. Jeśli taka kolumna zostanie wyświetlona jako pierwsza kolumna w klauzuli SELECT, kolumna zostanie dodana do górnego elementu.
Jeśli znak wieloznaczny (*) jest określony w klauzuli SELECT, zagnieżdżanie jest ustalane w taki sam sposób, jak wcześniej opisano, na podstawie kolejności zwracania wierszy przez aparat zapytań.
Następne kroki
Następujące artykuły zawierają więcej informacji na temat trybu AUTOMATYCZNEGO: