Как использовать символ & в типе XML T-SQL?

Когда я бегу:

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&amp...l&msdb&' AS NVARCHAR(MAX)), '&', '&')

Попробуйте: SELECT (SELECT name + '&' FROM sys.databases FOR XML PATH(''), TYPE).value('.', 'nvarchar(MAX)');

Dan Guzman 01.12.2018 04:21

Рад помочь, @OgrishMan. Я расширил свой комментарий ответом. Как гласит пословица, дай человеку рыбу и накорми его на день; научи человека ловить рыбу и накормишь его на всю жизнь.

Dan Guzman 01.12.2018 14:14
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
2
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предложение 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.

Другие вопросы по теме