Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

FOR XML PATH dans le serveur SQL et [text()]

Les autres réponses actuelles n'expliquent pas grand-chose d'où cela vient, ou offrent simplement des liens vers des sites mal formatés et ne répondent pas vraiment à la question.

Dans de nombreuses réponses sur le Web pour regrouper des chaînes, il y a les réponses copier-coller sans beaucoup d'explications sur ce qui se passe. Je voulais mieux répondre à cette question parce que je me posais la même question, et aussi donner un aperçu de ce qui se passe réellement dans l'ensemble.

tldr ;

En bref, il s'agit d'une syntaxe pour aider à transformer la sortie XML lors de l'utilisation de FOR XML PATH qui utilise des noms de colonne (ou des alias) pour structurer la sortie. Si vous nommez votre colonne text() les données seront représentées sous forme de texte dans la balise racine.

<row>
    My record's data
<row>

Dans les exemples que vous voyez en ligne pour savoir comment regrouper des chaînes et concat avec , ce n'est peut-être pas évident (sauf pour le fait que votre requête a ce petit for xml partie) que vous construisez réellement un fichier XML avec une structure spécifique (ou plutôt, un manque de structure) en utilisant FOR XML PATH ('') . Le ('') supprime les balises xml racine et recrache simplement les données.

L'accord avec AS [text()]

Comme d'habitude, AS agit pour nommer ou renommer l'alias de colonne. Dans cet exemple, vous aliasez cette colonne en tant que [text()] . Le [] s sont simplement les délimiteurs de colonne standard de SQL Server, souvent inutiles, sauf aujourd'hui puisque notre nom de colonne a () s. Cela nous laisse avec text() pour notre nom de colonne.

Contrôle de la structure XML avec les noms de colonne

Lorsque vous utilisez FOR XML PATH vous produisez un fichier XML et pouvez contrôler la structure avec vos noms de colonnes. Une liste détaillée des options peut être trouvée ici :https://msdn.microsoft .com/en-us/library/ms189885.aspx

Un exemple inclut le début de votre nom de colonne par un signe @, tel que :

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

Cela déplacerait les données de cette colonne vers un attribut de la ligne xml actuelle, par opposition à un élément qu'elle contient. Vous vous retrouvez avec

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

Alors, revenons à [text()] . Il s'agit en fait de spécifier un XPath Node Test . Dans le contexte de MS Sql Server, vous pouvez en savoir plus sur cette désignation ici . Fondamentalement, cela aide à déterminer le type d'élément auquel nous ajoutons ces données, comme un nœud normal (par défaut), un commentaire xml ou, dans cet exemple, du texte dans la balise.

Un exemple utilisant quelques mouvements pour structurer la sortie

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

Notez que nous utilisons quelques désignations dans nos noms de colonnes :

  • @color  :un attribut de balise
  • text() :du texte pour cette balise racine
  • comment() :un commentaire xml
  • info/text() :du texte dans une balise xml spécifique, <info>

La sortie ressemble à ceci :

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

Pour résumer, comment ces outils peuvent-ils regrouper et concaténer des chaînes ?

Ainsi, avec les solutions que nous voyons pour regrouper des chaînes en utilisant FOR XML PATH , il y a deux éléments clés.

  • AS [text()]  :Écrit les données sous forme de texte, au lieu de les envelopper dans une balise
  • FOR XML PATH ('') :Renomme la balise racine en '' , ou plutôt, le supprime entièrement

Cela nous donne une sortie "XML" (guillemets aériens) qui n'est essentiellement qu'une chaîne.

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

renvoie

tim, that guy, 

À partir de là, il suffit de joindre ces données à l'ensemble de données plus large dont elles proviennent.