次の方法で共有


FOR XML で AUTO モードを使用する

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 に追加されます。

これらの列の値を比較する場合、比較する列の種類が テキストntextimage、または xml の場合、FOR XML では、値が異なり、比較されないと見なされます。 これは、大きなオブジェクトの比較がサポートされていないためです。 選択した各行の結果に要素が追加されます。 (n)varchar(max) 列と varbinary(max) 列が比較されることに注意してください。

集計列または計算列の場合と同様に、SELECT 句の列を FROM 句で識別されたテーブルに関連付けることができない場合、列がリスト内で見つかった場合、その列は XML ドキュメント内の最も深い入れ子レベルに追加されます。 このような列が SELECT 句の最初の列として表示される場合、その列は最上位の要素に追加されます。

SELECT 句でアスタリスク (*) ワイルドカード文字が指定されている場合、入れ子は、クエリ エンジンによって返される行の順序に基づいて、前に説明したのと同じ方法で決定されます。

このセクションにて

次のトピックでは、AUTO モードの詳細について説明します。

こちらもご覧ください

SELECT (Transact-SQL)
FOR XML (SQL Server)