数据库单表查询中AUTO模式和RAW模式差别不大,但多表查询时AUTO模式会将查询结果作为嵌套XML元素返回。因此与RAW模式相比,AUTO模式对于生成简单的层次结构,功能强大了不少,但如果需要生成更复杂的层次结构的话,那就需要使用PATH模式了。
那么在多表查询的时候,AUTO模式是如何生成嵌套的XML元素的呢?
首先,AUTO模式有如下三个规则:
1,在FROM子句内,查询显示的列所在的表都会表示为一个XML元素。如果在 FOR XML子句中指定了可选的ELEMENTS选项,SELECT 子句中列出的列将映射到属性或子元素。
2,生成的XML中,XML层次结构是根据在查询子句中表出现的顺序产生的。因此,在SELECT子句中指定的列名顺序非常重要。出现的第一个表名形成的是所生成的XML文档的顶级元素,第二个表名则形成顶级元素的子元素,依此类推。
3 如果查询子句的列所在的表名已经出现过了,那么该列将作为你创建的元素的属性,而不是新添加一个级别。但是如果指定了ELEMENTS,则该列将作为元素添加。
通过下面这个实例详细说明下如上的三个规则:
SELECT Cust.CustomerID,
OrderHeader.CustomerID,
OrderHeader.SalesOrderID,
Detail.SalesOrderID, Detail.LineTotal,Detail.ProductID,
Product.Name,
Detail.OrderQty,Product.ProductID
FROM Cust,
OrderHeader,
Detail,
Product
WHERE Cust.CustomerID = OrderHeader.CustomerID
AND OrderHeader.SalesOrderID = Detail.SalesOrderID
AND Detail.ProductID = Product.ProductID
ORDER BY OrderHeader.CustomerID,
OrderHeader.SalesOrderID
FOR XML AUTO
查询结果如下:
<Cust CustomerID="117">
<OrderHeader CustomerID="117" SalesOrderID="47660">
<Detail SalesOrderID="47660" LineTotal="4.69794" ProductID="765" OrderQty="1">
<Product Name="Road-650 Black, 58" ProductID="765" />
</Detail>
</OrderHeader>
<OrderHeader CustomerID="117" SalesOrderID="49857">
<Detail SalesOrderID="49857" LineTotal="4.4994" ProductID="852" OrderQty="1">
<Product Name="Women's Tights, S" ProductID="852" />
</Detail>
</OrderHeader>
</Cust>
查询中出现了Cust,OrderHeader,Detail,Product这四个表,可以看到这段XML就相应有了四个元素,并且元素顺序与表名出现的顺序相一致,而查询的所有列名就是相应的表名元素的属性。同时可以看到,与RAW模式生成简单ROW元素的XML单级层次(详情请参考浅析数据库的FOR XML的应用-RAW模式)相比,此时XML有着较为复杂的层次结构。
好了,我们再加上FOR XML AUTO,ELEMENTS选项,看看结果:
<Cust>
<CustomerID>117</CustomerID>
<OrderHeader>
<CustomerID>117</CustomerID>
<SalesOrderID>47660</SalesOrderID>
<Detail>
<SalesOrderID>47660</SalesOrderID>
<LineTotal>4.697940000000000e+002</LineTotal>
<ProductID>765</ProductID>
<OrderQty>1</OrderQty>
<Product>
<Name>Road-650 Black, 58</Name>
<ProductID>765</ProductID>
</Product>
</Detail>
</OrderHeader>
<OrderHeader>
<CustomerID>117</CustomerID>
<SalesOrderID>49857</SalesOrderID>
<Detail>
<SalesOrderID>49857</SalesOrderID>
<LineTotal>4.499400000000000e+001</LineTotal>
<ProductID>852</ProductID>
<OrderQty>1</OrderQty>
<Product>
<Name>Women's Tights, S</Name>
<ProductID>852</ProductID>
</Product>
</Detail>
</OrderHeader>
</Cust>
每个列名都成为了一个元素,可见ELEMENTS选项在RAW和AUTO中的作用都是一样的。
那么,作为顶级元素的cust,如何确定它的新的开始位置呢?在确定嵌套元素的方式时,AUTO模式试探法将比较相邻行中的列值。将比较除ntext,text,image和xml 类型之外的所有类型的列。假如现在有cust这样的查询列:Cust.CustomerID, Cust.name,假如没有指定cust的主键的话,那么就会比较这两列,只要其中有任一列的值不一样,那么就会重新开始一个新的cust元素。
<Cust CustomerID="117" name="name">
<OrderHeader CustomerID="117" SalesOrderID="47660">
<Detail SalesOrderID="47660" LineTotal="4.697940000000000e+002" ProductID="765" OrderQty="1">
<Product Name="Road-650 Black, 58" ProductID="765" />
</Detail>
</OrderHeader>
</Cust>
<Cust CustomerID="117" name="name2">
<OrderHeader CustomerID="118" SalesOrderID="49857">
<Detail SalesOrderID="49857" LineTotal="4.499400000000000e+001" ProductID="852" OrderQty="1">
<Product Name="Women's Tights, S" ProductID="852" />
</Detail>
</OrderHeader>
</Cust>
如果两列的值都一样,那么返回的结果就只有一个。
<Cust CustomerID="117" name="name">
<OrderHeader CustomerID="117" SalesOrderID="47660">
<Detail SalesOrderID="47660" LineTotal="4.697940000000000e+002" ProductID="765" OrderQty="1">
<Product Name="Road-650 Black, 58" ProductID="765" />
</Detail>
</OrderHeader>
</Cust>
如果指定主键,那么每个主键就确定了一个新cust的开始。





