Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

FOR XML PATH no servidor SQL e [text()]


As outras respostas atuais não explicam muito sobre de onde vem isso, ou apenas oferecem links para sites mal formatados e não respondem realmente à pergunta.

Em muitas respostas na web para agrupar strings, existem as respostas de copiar e colar sem muita explicação do que está acontecendo. Eu queria responder melhor a essa pergunta porque estava me perguntando a mesma coisa e também dar uma visão do que realmente está acontecendo em geral.

tldr;


Resumindo, esta é a sintaxe para ajudar a transformar a saída XML ao usar FOR XML PATH que usa nomes de coluna (ou aliases) para estruturar a saída. Se você nomear sua coluna text() os dados serão representados como texto dentro da tag raiz.
<row>
    My record's data
<row>

Nos exemplos que você vê online sobre como agrupar strings e concatenar com , pode não ser óbvio (exceto pelo fato de sua consulta ter aquele pequeno for xml parte) que você está realmente construindo um arquivo XML com uma estrutura específica (ou melhor, falta de estrutura) usando FOR XML PATH ('') . O ('') está removendo as tags xml raiz e apenas cuspindo os dados.

O acordo com AS [text()]


Como de costume, AS está agindo para nomear ou renomear o alias da coluna. Neste exemplo, você está usando o alias desta coluna como [text()] . O [] s são simplesmente delimitadores de coluna padrão do SQL Server, muitas vezes desnecessários, exceto hoje, pois nosso nome de coluna tem () s. Isso nos deixa com text() para o nome da nossa coluna.

Controlando a estrutura XML com nomes de coluna


Quando você está usando FOR XML PATH você está gerando um arquivo XML e pode controlar a estrutura com os nomes das colunas. Uma lista detalhada de opções pode ser encontrada aqui:https://msdn.microsoft .com/en-us/library/ms189885.aspx

Um exemplo inclui iniciar o nome da coluna com um sinal @, como:
SELECT color as '@color', name
FROM #favorite_colors
FOR XML PATH

Isso moveria os dados dessa coluna para um atributo da linha xml atual, em vez de um item dentro dela. Você acaba com
<row color="red">
  <name>tim</name>
</row>
<row color="blue">
  <name>that guy</name>
</row>

Então, de volta para [text()] . Na verdade, isso está especificando um XPath Node Test . No contexto do MS Sql Server, você pode aprender sobre essa designação aqui . Basicamente, ele ajuda a determinar o tipo de elemento ao qual estamos adicionando esses dados, como um nó normal (padrão), um comentário xml ou, neste exemplo, algum texto dentro da tag.

Um exemplo usando alguns movimentos para estruturar a saída

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

Observe que estamos usando algumas designações em nossos nomes de coluna:
  • @color :um atributo de tag
  • text() :algum texto para esta tag raiz
  • comment() :um comentário xml
  • info/text() :algum texto em uma tag xml específica, <info>

A saída fica assim:
<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>

Resumindo, como essas ferramentas podem agrupar e concatenar strings?


Então, com as soluções que vemos para agrupar strings usando FOR XML PATH , há dois componentes principais.
  • AS [text()] :grava os dados como texto, em vez de envolvê-los em uma tag
  • FOR XML PATH ('') :Renomeia a tag raiz para '' , ou melhor, remove-o completamente

Isso nos dá uma saída "XML" (aspas no ar) que é essencialmente apenas uma string.
SELECT name + ', ' AS [text()] -- no 'name' tags
FROM #favorite_colors
FOR XML PATH ('')  -- no root tag

retorna
tim, that guy, 

A partir daí, é apenas uma questão de juntar esses dados de volta ao conjunto de dados maior de onde vieram.