pour la sortie du chemin xml ('')

9

Quand je lance ce qui suit

select t.type
  from (values ('Green'),('Blue'),('Red')) as t(type)
   for xml path('')

Je reçois cette sortie

<type>Green</type>
<type>Blue</type>
<type>Red</type>

Si je lance ce qui suit

select t.type + '/'
  from (values ('Green'),('Blue'),('Red')) as t(type)
   for xml path('')

Je reçois cette sortie

Green/Blue/Red/

Pourquoi l'ajout de la concaténation dans la sélection entraîne-t-il la suppression des balises de type et la sortie sur une seule ligne du fichier xml? Exécution de SQL Server 2012.

Kevin
la source

Réponses:

15

XML est bonkers

Lorsque vous ajoutez la chaîne concaténée, vous perdez «l'élément path».

Par exemple, si vous faites cela:

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML PATH('');

SELECT t.type + '/' 
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML PATH('type');

Vous récupérez ceci:

<type>Green/</type>
<type>Blue/</type>
<type>Red/</type>

Le nom ou l'alias de la colonne agit comme élément de chemin.

Quelques autres exemples qui pourraient aider

En utilisant RAW, ELEMENTS

SELECT t.type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, ELEMENTS;

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, ELEMENTS;

Dans le premier exemple, vous obtenez le nom d'élément générique "ligne", mais dans le second, vous obtenez ligne / type.

Lors de l'utilisation RAW, TYPE:

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, TYPE;

SELECT t.type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, TYPE;

La première requête renvoie un XML valide, la seconde renvoie une erreur car l'élément path n'a pas d'identifiant.

À l'aide de AUTO, l'alias de table et le nom de colonne se transforment en chemin:

SELECT type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

SELECT type 
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

Mais sans alias, vous obtenez une erreur similaire:

SELECT type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

Je FOR XML EXPLICITdonnerais un exemple avec mais il serait irresponsable de ma part de commencer à boire dès maintenant.

Erik Darling
la source