Compartir a través de


Consultas FOR XML anidadas

En SQL Server 2000, puede especificar la cláusula FOR XML sólo en el nivel superior de una consulta SELECT. El XML resultante se devuelve principalmente al cliente para el procesamiento adicional. Sin embargo, a partir de SQL Server 2005, el tipo de datos xml y la directiva TYPE en consultas FOR XML permiten que el XML que devuelven las consultas FOR XML pueda ser procesado de manera adicional en el servidor.

Procesar con variables de tipo xml

Puede asignar el resultado de la consulta FOR XML a una variable de tipo xml, o utilizar XQuery para consultar el resultado y asignar ese resultado a una variable de tipo xml para procesarlo más.

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" />

También puede procesar el XML devuelto en la variable, @x, utilizando alguno de los métodos de tipo de datos xml. Por ejemplo, puede recuperar el valor del atributo ProductModelID utilizando el método value().

DECLARE @i int
SET @i = (SELECT @x.value('/row[1]/@ProductModelID[1]', 'int'))
SELECT @i

En el siguiente ejemplo, el resultado de la consulta FOR XML se devuelve como un tipo xml porque se ha especificado la directiva TYPE en la cláusula FOR XML.

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=119 or ProductModelID=122
FOR XML RAW, TYPE,ROOT('myRoot')

El resultado es el siguiente:

<myRoot>
  <row ProductModelID="122" Name="All-Purpose Bike Stand" />
  <row ProductModelID="119" Name="Bike Wash" />
</myRoot>

Puesto que el resultado es de tipo xml, puede especificar uno de los métodos de tipo de datos xml directamente para este XML, como se muestra en la siguiente consulta. En la consulta, se utiliza el método query() del tipo de datos xml para recuperar el primer elemento secundario <row> del 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]')

El resultado es el siguiente:

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

Devolver resultados de consultas FOR XML internas a consultas externas como instancias de tipo xml

Puede escribir consultas FOR XML anidadas en las que el resultado de la consulta interna se devuelve como un tipo xml a la consulta externa. Por ejemplo:

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 lo siguiente en la consulta anterior:

  • El XML generado por la consulta FOR XML interna se agrega al XML generado por la consulta FOR XML externa.

  • En la siguiente consulta interna se especifica la directiva TYPE. Por lo tanto, los datos XML devueltos por la consulta interna son de tipo xml. Si no se especifica la directiva TYPE, el resultado de la consulta FOR XML interna se devuelve como nvarchar(max) y se crean entidades de los datos XML.

Controlar la forma de los datos XML resultantes

Las consultas FOR XML anidadas ofrecen mayor control en la definición de la forma de los datos XML resultantes. En SQL Server 2000, las consultas en modo RAW y AUTO generan XML centrado en atributos de forma predeterminada. Por ejemplo:

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW
 

El resultado centrado en atributos es el siguiente:

<row ProductModelID="122" Name="All-Purpose Bike Stand" />
<row ProductModelID="119" Name="Bike Wash" />

También es posible recuperar todo el XML centrado en elementos si se especifica la directiva ELEMENTS. Por ejemplo:

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 or ProductModelID=119
FOR XML RAW, ELEMENTS 

El resultado centrado en elementos es el siguiente:

<row>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</row>
<row>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</row>

Por consiguiente, en SQL Server 2000, se debe elegir XML centrado en atributos o centrado en elementos como resultado de una consulta. Sin embargo, a partir de SQL Server 2005, es posible utilizar consultas FOR XML anidadas para construir XML parcialmente centrado en atributos y parcialmente centrado en elementos.

Para obtener más información sobre cómo especificar XML centrado en atributos y XML centrado en elementos para las consultas FOR XML anidadas, vea Comparación de la consulta FOR XML con la consulta FOR XML anidada y Dar forma a XML con consultas FOR XML anidadas.

En SQL Server 2000, sólo puede construir elementos del mismo nivel escribiendo consultas que utilicen el modo EXPLICIT. Sin embargo, esto puede ser tedioso. A partir de SQL Server 2005, puede generar jerarquías XML que incluyen elementos del mismo nivel si especifica consultas FOR XML en modo AUTO anidadas. Para obtener más información, vea Generar elementos del mismo nivel con una consulta en modo AUTO anidada.

Con independencia del modo que se utilice, las consultas FOR XML anidadas proporcionan mayor control en la descripción de la forma del XML resultante. Se pueden usar en lugar de las consultas en modo EXPLICIT.

Ejemplos

Los temas siguientes proporcionan ejemplos de consultas FOR XML anidadas.