Consultas FOR XML aninhadas
No SQL Server 2000, é possível especificar a cláusula FOR XML apenas no nível superior de uma consulta SELECT. O XML resultante é retornado primeiramente ao cliente para processamento adicional. No entanto, a partir do SQL Server 2005, o tipo de dados xml e a diretiva TYPE em consultas FOR XML permitiram que o XML retornado por consultas FOR XML fosse processado adicionalmente no servidor.
Processando com variáveis de tipo xml
É possível atribuir o resultado da consulta FOR XML a uma variável de tipo xml ou usar XQuery para consultar o resultado e atribuir esse resultado a uma variável de tipo xml para processamento adicional.
DECLARE @x xml
SET @x=(SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW, TYPE)
SELECT @x
-- Result
--<row ProductModelID="122" Name="All-Purpose Bike Stand" />
--<row ProductModelID="119" Name="Bike Wash" />
Além disso, é possível processar o XML retornado na variável, @x, usando um dos métodos de tipo de dados xml. Por exemplo, é possível recuperar o valor do atributo ProductModelID usando o método value().
DECLARE @i int
SET @i = (SELECT @x.value('/row[1]/@ProductModelID[1]', 'int'))
SELECT @i
No exemplo a seguir, o resultado da consulta FOR XML é retornado como um tipo xml, porque a diretiva TYPE é especificada na cláusula FOR XML.
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=119 or ProductModelID=122
FOR XML RAW, TYPE,ROOT('myRoot')
Este é o resultado:
<myRoot>
<row ProductModelID="122" Name="All-Purpose Bike Stand" />
<row ProductModelID="119" Name="Bike Wash" />
</myRoot>
Como o resultado é de tipo xml, é possível especificar um dos métodos de tipo de dados xml diretamente em relação a esse XML, conforme mostrado na consulta a seguir. Na consulta, o método query() (tipo de dados xml) é usado para recuperar o primeiro elemento filho <row> do elemento <myRoot>.
SELECT (SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=119 or ProductModelID=122
FOR XML RAW, TYPE,ROOT('myRoot')).query('/myRoot[1]/row[1]')
Este é o resultado:
<row ProductModelID="122" Name="All-Purpose Bike Stand" />
Retornando resultados de consulta FOR XML interna para consultas externas como instâncias de tipo xml
É possível escrever consultas FOR XML aninhadas em que o resultado da consulta interna é retornado como um tipo xml para a consulta externa. Por exemplo:
SELECT Col1,
Col2,
( SELECT Col3, Col4
FROM T2
WHERE T2.Col = T1.Col
...
FOR XML AUTO, TYPE )
FROM T1
WHERE ...
FOR XML AUTO, TYPE
Observe o seguinte na consulta anterior:
O XML gerado pela consulta FOR XML interna é adicionado ao XML gerado pela FOR XML externa.
A consulta interna especifica a diretiva TYPE. Portanto os dados XML retornados pela consulta interna são de tipo xml. Se a diretiva TYPE não for especificada, o resultado da consulta FOR XML interna será retornado como nvarchar(max) e os dados XML terão a entidade definida.
Controlando a forma dos dados XML resultantes
Consultas FOR XML aninhadas fornecem mais controle para definir a forma dos dados XML resultantes. No SQL Server 2000, por padrão, as consultas em modo RAW e AUTO geram XML centrado em atributo. Por exemplo:
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW
Este é o resultado centrado em atributo:
<row ProductModelID="122" Name="All-Purpose Bike Stand" />
<row ProductModelID="119" Name="Bike Wash" />
Como alternativa, é possível recuperar todo o XML como centrado em elemento especificando a diretiva ELEMENTS. Por exemplo:
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW, ELEMENTS
Este é o resultado centrado em elemento:
<row>
<ProductModelID>122</ProductModelID>
<Name>All-Purpose Bike Stand</Name>
</row>
<row>
<ProductModelID>119</ProductModelID>
<Name>Bike Wash</Name>
</row>
Portanto, no SQL Server 2000, você deve escolher XML centrado em atributo ou centrado em elemento como o resultado de uma consulta. No entanto, a partir do SQL Server 2005, é possível usar consultas FOR XML para construir XML parcialmente centrado em atributo e parcialmente centrado em elemento.
Para obter mais informações sobre como especificar XML centrado em atributo e centrado em elemento com consultas FOR XML aninhadas, consulte Consulta FOR XML comparada com consulta FOR XML aninhada e Formando XML com consultas FOR XML aninhadas.
No SQL Server 2000, é possível construir irmãos apenas escrevendo consultas que usam modo EXPLICIT. No entanto isso pode ser trabalhoso. A partir do SQL Server 2005, é possível gerar hierarquias XML que incluem irmãos especificando consultas FOR XML aninhadas em modo AUTO. Para obter mais informações, consulte Gerando irmãos usando uma consulta aninhada em modo AUTO.
Independentemente do modo usado, consultas FOR XML aninhadas fornecem mais controle para descrever a forma do XML resultante. Elas podem ser usadas no lugar de consultas em modo EXPLICIT.
Exemplos
Os tópicos a seguir fornecem exemplos de consultas FOR XML aninhadas.
Consulta FOR XML comparada com consulta FOR XML aninhada
Compara uma consulta FOR XML de nível único com uma consulta FOR XML aninhada. Este exemplo inclui uma demonstração de como especificar XML centrado em atributo e centrado em elemento como o resultado da consulta.Gerando irmãos usando uma consulta aninhada em modo AUTO
Mostra como gerar irmãos usando uma consulta aninhada em modo AUTOUsando consultas FOR XML aninhadas no ASP.NET
Demonstra como um aplicativo ASPX pode usar FOR XML para retornar XML do SQL Server.Formando XML com consultas FOR XML aninhadas
Mostra como usar consultas FOR XML aninhadas para controlar a estrutura de um documento XML criado pelo SQL Server.