sql >> Base de Datos >  >> RDS >> Sqlserver

FOR XML PATH en el servidor SQL y [texto()]

Las otras respuestas actuales no explican mucho sobre el origen de esto, o simplemente ofrecen enlaces a sitios con formato deficiente y realmente no responden la pregunta.

En muchas respuestas en la web para agrupar cadenas, hay respuestas de copiar y pegar sin mucha explicación de lo que está sucediendo. Quería responder mejor a esta pregunta porque me preguntaba lo mismo y también dar una idea de lo que realmente está sucediendo en general.

tldr;

En resumen, esta es una sintaxis para ayudar a transformar la salida XML cuando se usa FOR XML PATH que utiliza nombres de columna (o alias) para estructurar la salida. Si nombra su columna text() los datos se representarán como texto dentro de la etiqueta raíz.

<row>
    My record's data
<row>

En los ejemplos que ve en línea sobre cómo agrupar cadenas y concatenar con , puede que no sea obvio (excepto por el hecho de que su consulta tiene ese pequeño for xml part) que en realidad está creando un archivo XML con una estructura específica (o mejor dicho, sin estructura) usando FOR XML PATH ('') . El ('') está eliminando las etiquetas raíz xml y simplemente escupiendo los datos.

El trato con AS [text()]

Como de costumbre, AS está actuando para nombrar o cambiar el nombre del alias de la columna. En este ejemplo, está asignando un alias a esta columna como [text()] . El [] s son simplemente los delimitadores de columna estándar de SQL Server, a menudo innecesarios, excepto hoy en día, ya que nuestro nombre de columna tiene () s. Eso nos deja con text() para nuestro nombre de columna.

Control de la estructura XML con nombres de columnas

Cuando está utilizando FOR XML PATH está generando un archivo XML y puede controlar la estructura con los nombres de sus columnas. Puede encontrar una lista detallada de opciones aquí:https://msdn.microsoft .com/en-us/library/ms189885.aspx

Un ejemplo incluye comenzar el nombre de su columna con un signo @, como:

SELECT color as '@color', name
FROM #favorite_colors
FOR XML PATH

Esto movería los datos de esta columna a un atributo de la fila xml actual, a diferencia de un elemento dentro de ella. Terminas con

<row color="red">
  <name>tim</name>
</row>
<row color="blue">
  <name>that guy</name>
</row>

Entonces, volvamos a [text()] . En realidad, esto especifica una Prueba de nodo XPath . En el contexto de MS Sql Server, puede obtener información sobre esta designación aquí . Básicamente, ayuda a determinar el tipo de elemento al que estamos agregando estos datos, como un nodo normal (predeterminado), un comentario xml o, en este ejemplo, algún texto dentro de la etiqueta.

Un ejemplo usando algunos movimientos para estructurar la salida

SELECT 
  color as [@color]
  ,'Some info about ' + name AS [text()]
  ,name + ' likes ' + color AS [comment()]
  ,name
  ,name + ' has some ' + color + ' things' AS [info/text()]
FROM #favorite_colors
FOR XML PATH

Note que estamos usando algunas designaciones en nuestros nombres de columna:

  • @color :un atributo de etiqueta
  • text() :algo de texto para esta etiqueta raíz
  • comment() :un comentario xml
  • info/text() :algún texto en una etiqueta xml específica, <info>

La salida se ve así:

<row color="red">
    Some info about tim
    <!--tim likes red-->
    <name>tim</name>
    <info>tim has some red things</info>
</row>
<row color="blue">
    Some info about that guy
    <!--that guy likes blue-->
    <name>that guy</name>
    <info>that guy has some blue things</info>
</row>

Resumiendo, ¿cómo pueden estas herramientas agrupar y concatenar cadenas?

Entonces, con las soluciones que vemos para agrupar cadenas usando FOR XML PATH , hay dos componentes clave.

  • AS [text()] :escribe los datos como texto, en lugar de envolverlos en una etiqueta
  • FOR XML PATH ('') :cambia el nombre de la etiqueta raíz a '' , o más bien, lo elimina por completo

Esto nos da una salida "XML" (comillas de aire) que es esencialmente solo una cadena.

SELECT name + ', ' AS [text()] -- no 'name' tags
FROM #favorite_colors
FOR XML PATH ('')  -- no root tag

regresa

tim, that guy, 

A partir de ahí, solo es cuestión de volver a unir esos datos con el conjunto de datos más grande del que proceden.