La cláusula FOR XML (FOR XML RAW, FOR XML AUTO, FOR XML PATH, y las opciones ROOT y ELEMENTS) permite devolver una consulta SQL como un Fragmento o Documento XML, en lugar de como un conjunto de filas, lo que resulta de gran utilidad en muchos casos, y siendo una características de SQL Server disponible desde hace ya muchos años (SQL Server 2000, tela !), aunque resulte aún desconocida para muchas personas (especialmente para quienes no trabajan habitualmente con SQL Server). La cláusula FOR XML se incluye al final de la consulta SQL, como veremos en los siguientes ejemplos.
FOR XML RAW
Quizás el ejemplo más sencillo por el que empezar sea FOR XML RAW, el cual devuelve cada fila como un elemento ROW. Téngase en cuenta que el orden de los campos en la SELECT no afectará al resultado de la consulta ya que en todos los casos se obtendrá un elemento ROW para cada fila (más adelante veremos que con FOR XML AUTO esto no es así). A continuación tenemos un primer ejemplo de una consulta SQL con la cláusula FOR XML RAW.
SELECT ORD.OrderId, ORD.OrderDate, ORD.Amount, CUS.Name, CUS.Country FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML RAW
|
En consecuencia, el resultado obtenido para la siguiente consulta SQL sería el siguiente.
Si lo deseamos, podemos sobrescribir el elemento ROW con el valor que deseemos, pasándolo como parámetro a la opción RAW, tal y como se muestra en la siguiente consulta SQL de ejemplo.
SELECT ORD.OrderId, ORD.OrderDate, ORD.Amount, CUS.Name, CUS.Country FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML RAW('Pedido')
|
El resultado de ejecución de la anterior consulta SQL sería el siguiente.
FOR XML AUTO
La cláusula FOR XML AUTO tiene la peculiaridad de que por defecto utilizará Elementos HTML diferentes para los campos de las diferentes tablas. Como lo mejor es verlo con un caso práctico, tomemos la siguiente consulta SQL.
SELECT ORD.OrderId, ORD.OrderDate, ORD.Amount, CUS.Name, CUS.Country FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML AUTO
|
El resultado de ejecución de dicha consulta SQL sería el siguiente.
Además, la cláusula FOR XML AUTO tiene la peculiaridad de que en función del orden de las columnas en la consulta SQL, el resultado de la ejecución puede variar ligeramente. Por ejemplo, vamos a alterar la consulta SQL anterior, para poner primero las columnas de la tabla Customers y luego las columnas de la tabla Orders (justo al revés que en el ejemplo anterior).
SELECT CUS.Name, CUS.Country, ORD.OrderId, ORD.OrderDate, ORD.Amount FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML AUTO
|
Ahora, el resultado de ejecución de dicha consulta SQL sería el siguiente.
La opción ELEMENTS
Tanto con FOR XML RAW y FOR XML ELEMENTS podemos utilizar la opción ELEMENTS para evitar la utilización de Atributos y emplear siempre elementos HTML. No tiene mayor misterio, en cualquier caso, vamos a tomar como ejemplo la anterior consulta SQL, y la vamos a alterar para incluir la opción ELEMENTS.
SELECT CUS.Name, CUS.Country, ORD.OrderId, ORD.OrderDate, ORD.Amount FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML AUTO, ELEMENTS
|
Ahora, el resulta de ejecución de dicha consulta SQL es el siguiente.
FOR XML PATH
La cláusula FOR XML PATH permite poder combinar Elementos y Atributos XML. En su forma básica, FOR XML PATH es similar a FOR XML RAW, ELEMENTS, creando un elemento ROW para cada fila, y en el interior de dicho elemento ROW se mostrará cada columna de la SELECT como un elemento independiente. Tomando como ejemplo la siguiente consulta SQL.
SELECT CUS.Name, CUS.Country, ORD.OrderId, ORD.OrderDate, ORD.Amount FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML PATH
|
El resultado de ejecución de dicha consulta SQL sería el siguiente.
Al utilizar la cláusula FOR XML PATH podemos sobrescribir el elemento ROW por el valor que deseemos, pasándolo como parámetro a la opción PATH. También podemos especificar qué campos deseamos como atributos, prefijándolos con una @ al utilizar alias de columnas en la SELECT, e incluso podemos especificar qué campos deseamos como sub-elementos o como atributos de los sub-elementos, en todos los casos utilizando alias de columnas en la SELECT, como podemos ver en la siguiente consulta SQL de ejemplo.
SELECT CUS.Name AS '@Name', CUS.Country AS '@Country' , ORD.OrderId AS 'Pedido/@ID', ORD.OrderDate AS 'Pedido/Fecha', ORD.Amount AS 'Pedido/Importe' FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML PATH('Cliente')
|
El resultado de ejecución de dicha consulta SQL sería el siguiente.
La opción ROOT
En todos los casos anteriores (FOR XML RAW, FOR XML AUTO, y FOR XML PATH), podemos utilizar la opción ROOT para incluir el elemento HTML raíz que deseemos, y así poder obtener un Documento XML en vez de un Fragmento XML. Para ver un caso práctico, podemos tomar la siguiente consulta SQL de ejemplo.
SELECT CUS.Name, CUS.Country, ORD.OrderId, ORD.OrderDate, ORD.Amount FROM dbo.Customers CUS INNER JOIN dbo.Orders ORD ON CUS.CustomerId = ORD.CustomerId WHERE CUS.CustomerId = 1 FOR XML AUTO, ELEMENTS, ROOT('RootElement')
|
El resultado de ejecución de la anterior consulta SQL sería el siguiente.
Despedida y Cierre
Hasta aquí llega el presente artículo, en el cual hemos presentado algunas de las posibilidades de las consultas FOR XML, para lo cual, hemos utilizado una misma consulta SQL que hemos alterado para mostrar el resultado obtenido en función de las opciones FOR XML utilizadas (FOR XML RAW, FOR XML AUTO, FOR XML PATH, y las opciones ROOT y ELEMENTS).
Poco más por hoy. Como siempre, confío que la lectura resulte de interés.