Когда я бегу:
SELECT name + '&'
FROM sys.databases
FOR XML PATH('');
Код возвращает это:
master&tempdb&model&msdb&
Я действительно хочу:
master&tempdb&model&msdb&
Я также пробовал:
SELECT name + CHAR(38)
FROM sys.databases
FOR XML PATH('');
Это тоже не работает. Как я могу получить ожидаемый результат в первую очередь?
Без чего-то вроде:
REPLACE(CAST('master&...l&msdb&' AS NVARCHAR(MAX)), '&', '&')
Рад помочь, @OgrishMan. Я расширил свой комментарий ответом. Как гласит пословица, дай человеку рыбу и накорми его на день; научи человека ловить рыбу и накормишь его на всю жизнь.


Предложение FOR XML по умолчанию возвращает текст, поэтому строка результата включает ссылки на предопределенные объекты XML, такие как & для амперсанда, для представления специальных символов в XML.
Чтобы избежать ссылок на сущности в результате, включите TYPE в предложение FOR XML, чтобы вернуть значение как строго типизированный XML вместо текста, что позволяет вызвать метод value на узле XML для получения значения как nvarchar(MAX) без ссылок на сущности:
SELECT (
SELECT name + '&'
FROM sys.databases
FOR XML PATH(''), TYPE
).value('(./text())[1]', 'nvarchar(MAX)');
В приведенном выше примере есть конечный амперсанд, как в исходном запросе. Один из способов избежать постороннего разделителя - использовать STUFF. Ниже приведен еще один пример, который добавляет разделитель к каждому значению и удаляет ненужный первый. Кроме того, спецификация значения (./text())[1] для одноэлементного узла улучшит производительность.
для более крупных запросов.
SELECT STUFF((
SELECT '&' + name
FROM sys.databases
FOR XML PATH(''), TYPE
).value('(./text())[1]', 'nvarchar(MAX)'), 1, 1, '');
Я добавлю, что вы можете избежать уродства XML для агрегированной конкатенации строк в SQL Server 2017+ и базе данных SQL Azure, используя гораздо более чистый и менее подробный метод STRING_AGG:
SELECT STRING_AGG(name, '&')
FROM sys.databases;
См. этот ответ для более подробного описания объединения строк с использованием FOR XML.
Попробуйте:
SELECT (SELECT name + '&' FROM sys.databases FOR XML PATH(''), TYPE).value('.', 'nvarchar(MAX)');