我正在使用T / SQL FOR XML技巧将一组值与定界符连接起来。我想对值中的定界符(在本例中为|)进行实体编码,但是FOR XML重新编码|。所以我最终以|
if object_id('tempdb..#t') is not null drop table #t
create table #t (v varchar(100))
insert #t(v) values ('Foo'),('A|B'),('Bar')
select (
select '|' + v AS [text()]
FROM #t
FOR XML PATH ('')
) + '|' as vConcat
-- Result of above = |Foo|A|B|Bar| -- delimiter in A|B not escaped
select (
select '|' + replace(v, '|', '|') AS [text()]
FROM #t
FOR XML PATH ('')
) + '|' as vConcat
-- Result of above = |Foo|A|B|Bar| -- delimiter double-escaped
有没有办法让FOR XML编码其他字符?还是有更好的方法在FOR XML中实现转义分隔符?
使用其他定界符不是我要找的答案。
我知道将整个表达式包装在替换中以撤消double编码是可行的,但是这并不使我感到非常优雅。
select replace((
select '|' + replace(v, '|', '|') AS [text()]
FROM #t
FOR XML PATH ('')
) + '|', '|', '|') as vConcat
-- Result of above = |Foo|A|B|Bar|
修改
为使问题更清楚,我想对常用的特殊XML字符进行实体编码(仅在原始值内)。
if object_id('tempdb..#t') is not null drop table #t
create table #t (v varchar(100))
insert #t(v) values ('F&o'),('A|B'),('Bar'),('A|B')
select (
select '|' + v AS [text()]
FROM #t
FOR XML PATH ('')
) + '|' as vConcat
-- Result of above = |F&o|A|B|Bar|A|B| -- special chars encoded but not delimiter in A|B value
select (
select '|' + replace(v, '|', '|') AS [text()]
FROM #t
FOR XML PATH ('')
) + '|' as vConcat
-- Result of above = |F&o|A|B|Bar|A|B| -- delimiter in A|B value double-encoded
-- Desired result = |F&o|A|B|Bar|A|B|
答案 0 :(得分:1)
您可以在XML上使用value()
。
SELECT (SELECT '|' + replace(v, '|', '|') AS [text()]
FROM #t
FOR XML PATH (''), TYPE).value('.', 'varchar(max)') + '|' vconcat;