2009-06-26 101 views
14

此代碼基本上將基於一個字符串中的位置的字符轉換爲另一個字符串中相同位置處的字符,並且它會針對表中的所有行運行。FOR XML PATH(''):轉義「特殊」字符

當我運行這個(簡體版):

DECLARE @R   char(40) 
DECLARE @U   char(40) 
SET @R=' [email protected]#$%^&*()_+'+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 
        ''+c.R 
        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 

我得到如下:

RowID  readable 
----------- --------------------------------------- 
1   a&#x20;simple&#x20;translation 
2   hello&#x20;world 
3   wow&#x20;you&#x20;ran&#x20;this 

但需要:

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

有什麼辦法,除了REPLACE() ,讓空間正確顯示?這也發生在換行符,在我的實際代碼中。

這可以用更好的方式重寫嗎?我基本上只是使用FOR XML PATH('')將各個行值連接在一起。

+0

我確定這是你的真實代碼,但你應該發佈一個更簡單的例子來說明同樣的問題。這是相當多的奇怪的代碼來消化,雖然問題可能會更簡單。 – 2009-06-26 23:56:24

+0

@John Saunders,我希望這是我的「真正的代碼」,因爲我現在就完成了!對不起,說最終的代碼會更復雜,因爲這是一個查詢的一小部分。 – 2009-06-29 17:20:27

回答

22

您得到的XML是正確的。它是XML,而不是文本,並且可以通過XML解析器以XML格式讀取。正如他們應該的那樣,特殊字符正確地逃脫了。無論您使用哪種客戶端模塊,該XML都應將其解析爲XML,而不是文本,然後才能正確顯示。

更新:

如果不明確,你需要在你的查詢做的是把XML作爲XML和文本,文本,不能混用XML文本,即:

;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 
        ''+c.R 
        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