Question : Concatenating with FOR XML PATH('') while dealing with special XML characters

Hello fellow experts.  I figured it was time to ask a question so here it goes.  

The goal is that for each A in table #t, there will be a single returned value which is the concatenation of all values in column b.  You will see that I am using a correlated sub-select to get the values, and everything works well for #t.a=2.  But since #t.a=1 has the & < and carriage return line feed in the data, the FOR XML PATH('') is converting them into their XML hex values respectively.  

Adding a group by will ensure that each #t.a is only returned once, that's not my concern.

So my question is this.  Come up with a creative, and efficient, way to return a single value for each #t.a that HOPEFULLY does not use a nested replace like I am doing in the third column below.

Points for effort, creativity and participation WILL be given.

Please do NOT suggest a cursor, while loop, or other RBAR based solution.  This HAS to be a single statement and PREFERABLY without the use of a UDF.

Thanks fellow experts and I look forward to your responses.
Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
create table #t
(a   int
,b   nvarchar(20)
)
go
insert into #t values(1,'a&b')
insert into #t values(1,'c<
d')
insert into #t values(2,'wx')
insert into #t values(2,'yz')
go
select a,b,
(select b+N'' 
        from #t 
        where a=t.a
        for xml path('')
       ) 'WITH xml CHARACTERS'
,replace(
replace(
replace(
replace(
replace(
replace(
replace(
(select b+N'' 
        from #t 
        where a=t.a
        for xml path('')
       )
,' ',char(20))
,'&','&')
,'<','<')
,'>','>')
,'
',char(10))
,'
',char(13))
,'	',char(9)) 'With XML Replaced'
 
from #t t
 
go
drop table #t
Open in New Window Select All

Answer : Concatenating with FOR XML PATH('') while dealing with special XML characters

Bugga, forgot the []...
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
use tempdb
go
create table #BG_Objects1 (a int,b int,c int)
create table #BG_Objects2 (a int,b int,[a & b] as a+b)
go
 
;with cte_concat as
  (
  select (select max(ordinal_position) from information_schema.columns c where c.table_name =i.table_name) max_num,
         ordinal_position, convert(varchar(1000),'['+column_name+']') as column_name, table_name 
  from information_schema.columns i where table_name like '#bg_objects%' and ordinal_position = 1
 
  union all
 
  select max_num,i.ordinal_position, convert(varchar(1000),rtrim(c.column_name) + ',[' + rtrim(i.column_name)+']'), c.table_name
  from cte_concat c
  inner join information_schema.columns i on c.ordinal_position + 1 = i.ordinal_position and c.table_name = i.table_name
  ) 
select table_name,column_name from cte_concat where ordinal_position = max_num
 
go
drop table #BG_Objects1
drop table #BG_Objects2
Open in New Window Select All
Random Solutions  
 
programming4us programming4us