Generowanie rodzeństwa za pomocą zagnieżdżonego zapytania w trybie AUTO
Dotyczy:SQL Server
Azure SQL Database
Azure SQL Managed Instance
W poniższym przykładzie pokazano, jak wygenerować rodzeństwo przy użyciu zagnieżdżonego zapytania w trybie AUTO. Jedynym innym sposobem generowania takiego kodu XML jest użycie trybu JAWNE. Może to być jednak kłopotliwe.
Przykład
To zapytanie konstruuje kod XML, który zawiera informacje o zamówieniach sprzedaży. Obejmuje to następujące elementy:
Informacje nagłówka zamówienia sprzedaży:
SalesOrderID
,SalesPersonID
, iOrderDate
.AdventureWorks2022
przechowuje te informacje w tabeliSalesOrderHeader
.Szczegóły zamówienia sprzedaży. Obejmuje to co najmniej jeden zamówiony produkt, cenę jednostkową i ilość zamówioną. Te informacje są przechowywane w tabeli
SalesOrderDetail
.Informacje o osobach sprzedaży. Jest to sprzedawca, który przyjął zamówienie. Tabela
SalesPerson
zawieraSalesPersonID
. W przypadku tego zapytania musisz dołączyć tę tabelę do tabeliEmployee
, aby znaleźć nazwę osoby sprzedaży.
Dwa odrębne zapytania SELECT
, które następują, generują XML z niewielką różnicą w strukturze.
Pytanie pierwsze generuje XML, w którym <SalesPerson>
i <SalesOrderHeader>
pojawiają się jako równorzędne elementy <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;
W poprzednim zapytaniu najbardziej zewnętrzna instrukcja SELECT
wykonuje następujące czynności:
Zapytanie do zestawu wierszy
SalesOrder
, określonego w klauzuliFROM
. Wynikiem jest kod XML z co najmniej jednym elementem<SalesOrder>
.Określa tryb
AUTO
i dyrektywęTYPE
.AUTO
tryb przekształca wynik zapytania w kod XML, a dyrektywaTYPE
zwraca wynik jako typ xml.Zawiera dwie zagnieżdżone instrukcje
SELECT
, rozdzielone przecinkiem. Pierwsze zagnieżdżone zapytanieSELECT
pobiera informacje o zamówieniach sprzedaży, nagłówkach i szczegółach, a drugie zagnieżdżone zapytanieSELECT
pobiera informacje o sprzedawcy.- Instrukcja
SELECT
, która pobieraSalesOrderID
,SalesPersonID
iCustomerID
, zawiera zagnieżdżoną instrukcjęSELECT ... FOR XML
(z trybemAUTO
i dyrektywąTYPE
), która zwraca szczegółowe informacje o zamówieniu sprzedaży.
- Instrukcja
Instrukcja SELECT
, która pobiera informacje o osobie sprzedaży, wykonuje zapytania dotyczące zestawu wierszy, SalesPerson
, utworzonego w klauzuli FROM
. Aby zapytania FOR XML
działały, należy podać nazwę anonimowego zestawu wierszy wygenerowanego w klauzuli FROM
. W tym przypadku podana nazwa to SalesPerson
.
Jest to wynik częściowy:
<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>
...
Następujące zapytanie generuje te same informacje o zamówieniu sprzedaży, z tą różnicą, że w wynikowym kodzie XML <SalesPerson>
jest wyświetlana jako element równorzędny <SalesOrderDetail>
:
<SalesOrder>
<SalesOrderHeader ...>
<SalesOrderDetail .../>
<SalesOrderDetail .../>
...
<SalesPerson .../>
</SalesOrderHeader>
</SalesOrder>
<SalesOrder>
...
</SalesOrder>
Jest to zapytanie:
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;
Jest to wynik:
<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>
Ponieważ dyrektywa TYPE
zwraca wynik zapytania jako typ xml, możesz wykonać zapytanie względem wynikowego kodu XML przy użyciu różnych metod typu danych xml. Aby uzyskać więcej informacji, zobacz metody typów danych xml . W poniższym zapytaniu zwróć uwagę na następujące kwestie:
Poprzednie zapytanie jest dodawane w klauzuli
FROM
. Wynik zapytania jest zwracany jako tabela. Zwróć uwagę na dodany aliasXmlCol
.Klauzula
SELECT
określa zapytanie XQuery dlaXmlCol
, które jest zwrócone w klauzuliFROM
. Metodaquery()
typu danych xml jest używana w specyfikacji zapytania XQuery. Aby uzyskać więcej informacji, zobacz query() Method (xml Data Type).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);