FOR XML (SQL Server) で説明されているように、AUTO モードは入れ子になった XML 要素としてクエリ結果を返します。 これにより、クエリ結果から生成される XML の形状をあまり制御できません。 AUTO モードのクエリは、単純階層を生成する場合に便利です。 ただし、 FOR XML で EXPLICIT モードを使用 し、 FOR XML で PATH モードを使用 すると、クエリ結果から XML の形状を決定する際の制御と柔軟性が向上します。
SELECT 句に少なくとも 1 つの列がリストされている FROM 句の各テーブルは、XML 要素として表されます。 オプションの ELEMENTS オプションが FOR XML 句で指定されている場合、SELECT 句にリストされている列は属性またはサブ要素にマップされます。
結果の XML における要素の入れ子の XML 階層は、SELECT 句で指定された列によって識別されるテーブルの順序に基づいています。 したがって、SELECT 句で列名を指定する順序は重要です。 識別される最初の左端のテーブルは、結果の XML ドキュメントの最上位の要素を形成します。 SELECT ステートメントの列で識別される 2 番目の左端のテーブルは、最上位要素内にサブ要素を形成します。
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 の 3 つの列で、OrderHeader テーブルを参照します。 したがって、 <
OrderHeader
> 要素は <Cust
> 要素のサブ要素として追加され、3 つの列は <OrderHeader
>の属性として追加されます。次に、Cust.CustomerType 列は、Cust.CustomerID 列によって既に識別された Cust テーブルを再度参照します。 そのため、新しい要素は作成されません。 代わりに、CustomerType 属性が、以前に作成された <
Cust
> 要素に追加されます。このクエリでは、テーブル名のエイリアスを指定します。 これらのエイリアスは、対応する要素名として表示されます。
ORDER BY は、すべての子を 1 つの親の下にグループ化するために必要です。
このクエリは前のクエリと似ていますが、SELECT 句では、Cust テーブルの列の前に OrderHeader テーブルの列が指定されています。 したがって、最初 <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) が 1 つの行から次の行に比較されます。 値が異なる場合は、新しい <Cust> 要素が XML に追加されます。
これらの列の値を比較する場合、比較する列の種類が テキスト、 ntext、 image、または xml の場合、FOR XML では、値が異なり、比較されないと見なされます。 これは、大きなオブジェクトの比較がサポートされていないためです。 選択した各行の結果に要素が追加されます。 (n)varchar(max) 列と varbinary(max) 列が比較されることに注意してください。
集計列または計算列の場合と同様に、SELECT 句の列を FROM 句で識別されたテーブルに関連付けることができない場合、列がリスト内で見つかった場合、その列は XML ドキュメント内の最も深い入れ子レベルに追加されます。 このような列が SELECT 句の最初の列として表示される場合、その列は最上位の要素に追加されます。
SELECT 句でアスタリスク (*) ワイルドカード文字が指定されている場合、入れ子は、クエリ エンジンによって返される行の順序に基づいて、前に説明したのと同じ方法で決定されます。
このセクションにて
次のトピックでは、AUTO モードの詳細について説明します。