FOR XML PATH (”): Escape de caracteres “especiais”

Este código basicamente traduz caracteres baseados em posição em uma string para o caractere na mesma posição em outra string e é executado para todas as linhas na tabela.

Quando eu corro isso (versão simplificada):

DECLARE @R char(40) DECLARE @U char(40) SET @R=' abcdefghijklmnopqrstuvwxyz!@#$%^&*()_+'+char(181) SET @U=REVERSE(@R) DECLARE @TestTable TABLE (RowID int identity(1,1) primary key, Unreadable varchar(500)) INSERT INTO @TestTable VALUES ('+µt$zw!*µsu+yt!+s$xy') INSERT INTO @TestTable VALUES ('%*!!xµpxu!(') INSERT INTO @TestTable VALUES ('pxpµnxrµu+yµs%$t') ;WITH CodeValues AS ( SELECT Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA FROM Numbers WHERE Number<=LEN(@R) ) SELECT t.RowID ,(SELECT ''+cR FROM Numbers n INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA WHERE n.Number<=LEN(t.Unreadable) FOR XML PATH('') ) AS readable FROM @TestTable t 

Eu recebo o seguinte:

 RowID readable ----------- --------------------------------------- 1 a simple translation 2 hello world 3 wow you ran this 

Mas precisa de:

 RowID readable ----------- --------------------------------------- 1 a simple translation 2 hello world 3 wow you ran this 

Existe alguma maneira, além de REPLACE() , para que os espaços apareçam corretamente? Isso também acontece em quebras de linha, no meu código real.

Isso pode ser reescrito de uma maneira melhor? Eu basicamente usei o FOR XML PATH('') para concatenar os valores de linha individuais juntos.

O XML que você obtém está correto. É XML , não texto e legível como XML por um analisador XML. Caracteres especiais são devidamente escapados, como deveriam ser. Qualquer que seja o módulo do cliente que consuma esse XML, ele deve analisá-lo como XML, não como texto e, em seguida, será exibido corretamente.

Atualizar:

Caso não esteja claro, tudo o que você precisa fazer em sua consulta é tratar XML como XML e texto como texto, não misturar XML como texto, ou seja:

 ;WITH CodeValues AS ( SELECT Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA FROM Numbers WHERE Number<=LEN(@R) ) , XmlValues AS ( SELECT t.RowID ,(SELECT ''+cR FROM Numbers n INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA WHERE n.Number<=LEN(t.Unreadable) FOR XML PATH(''), TYPE ) AS readable FROM @TestTable t) SELECT x.RowId, x.readable.value('.', 'VARCHAR(8000)') as readable FROM XmlValues AS x 
    Intereting Posts