для вывода в формате XML ('')

9

Когда я запускаю следующее

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

Я получаю этот вывод

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

Если я запускаю следующее

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

Я получаю этот вывод

Green/Blue/Red/

Почему добавление конкатенации в select приводит к удалению тегов типа и выводу их в одну строку в XML-файле? Запуск SQL Server 2012.

kevinnwhat
источник

Ответы:

15

XML мешает

Когда вы добавляете объединенную строку, вы теряете «элемент пути».

Например, если вы делаете это:

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');

Вы получите это обратно:

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

Имя столбца или псевдоним действует как элемент пути.

Некоторые другие примеры, которые могут помочь

С помощью 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;

В первом примере вы получаете общее имя элемента row, но во втором вы получите row / type.

При использовании 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;

Первый запрос возвращает действительный XML-код, второй выдает ошибку, поскольку элемент пути не имеет идентификатора.

Используя AUTOпсевдоним таблицы и имя столбца превращается в путь:

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;

Но без псевдонима вы получите похожую ошибку:

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

Я бы FOR XML EXPLICITпривел пример, но для меня было бы безответственно начинать пить прямо сейчас.

Эрик Дарлинг
источник