Добавить к важному замечанию Гордона:
DECLARE @tbl TABLE(id INT, displayname VARCHAR(100));
INSERT INTO @tbl VALUES(1,'value 1.1'),(1,'value 1.2')
,(2,'value 2.1'),(2,'value 2.2.'),(2,'value 2.3 with special characters $<>')
,(3,'value 3.1');
- запрос
SELECT id, displayname =
STUFF((SELECT DISTINCT '<br/>, ' + displayname
FROM @tbl b
WHERE b.id = a.id
FOR XML PATH, TYPE
).value('.[1]', 'nvarchar(max)'), 1, 7, '')
FROM @tbl a
GROUP BY id;
Важно знать, что любой текст в пределах XML должен быть экранирован правильно. Включение специальных символов не проблема, но вы должны использовать TYPE
и .value()
для чтения из XML с неявным повторным экранированием.
Результат (внимательно посмотрите на вторую строку!):
value 1.1<br/>, value 1.2
value 2.1<br/>, value 2.2.<br/>, value 2.3 with special characters $<>
value 3.1
Проблема теперь в следующем: это может привести к поломке HTML ...
Мое предложение: придерживайтесь X HTML и старайтесь избегать любого строкового кодирования
DECLARE @tbl TABLE(id INT, displayname VARCHAR(100));
INSERT INTO @tbl VALUES(1,'value 1.1'),(1,'value 1.2')
,(2,'value 2.1'),(2,'value 2.2.'),(2,'value 2.3 with special characters $<>')
,(3,'value 3.1');
SELECT id
, displayname = (SELECT displayname AS [*]
FROM @tbl b
WHERE b.id = a.id
FOR XML PATH('line'),TYPE).query('for $l in /line
return
($l/text(),<br/>)
')
FROM @tbl a
GROUP BY id;
Результат XML напечатан и может быть помещен в другие X HTML, не думая о сбежавших сущностях:
value 1.1<br />value 1.2<br />
value 2.1<br />value 2.2.<br />value 2.3 with special characters $<><br />
value 3.1<br />
Подсказка: ответ GMB тоже будет работать
В ответе GMB TYPE
с .value()
не используется (как было рекомендовано в нормальных случаях). Вы можете безопасно использовать этот подход, если имеете дело со строками. Но имейте в виду, что смешивать XML и строковые подходы очень опасно из-за неявного экранирования ...