2017-03-16 17 views
2

我有一個數字轉換成一組ASCII字符,然後查詢嘗試將它們連接成一個字符串:連接具有FOR XML改變編碼

declare @number int = 651854564 

;with cte as (
select @number prev_nr 
    , cast(char(@number % 256) as nvarchar(100)) nextchar 
union all 
select prev_nr/256 prev_nr 
    , cast(char((prev_nr/256) % 256) as nvarchar(100)) nextchar 
from cte 
where prev_nr <> 0) 
select 
    cast(nextchar + '' as nvarchar(100)) 
from cte 
where prev_nr <> 0 
for xml path (''); 

中的人物是由於拆分上述號碼個人字符是:

characters 
ä 
‚ 
Ú 
& 

但是試圖與FOR XML將它們串聯在它們改變編碼,以便在端&進行變換和連接成最終的結果是:ä‚Ú&amp;

我該如何解決這個問題,以便我可以得到正確的編碼並生成ä‚Ú&結果?

我已經嘗試將所有內容轉換爲nvarchar(100),但我有一種感覺,這沒有任何效果(實際上它幾乎與編碼無關 - 或者至少在我的場景中沒有幫助)。

我也嘗試了着名的STUFFFOR XML但這並沒有真正的幫助。

回答

5

使用type directive in for xml queries

試試這個:

declare @number int = 651854564 

;with cte as (
select @number prev_nr 
    , cast(char(@number % 256) as nvarchar(100)) nextchar 
union all 
select prev_nr/256 prev_nr 
    , cast(char((prev_nr/256) % 256) as nvarchar(100)) nextchar 
from cte 
where prev_nr <> 0 
) 

select (select 
    cast(nextchar + '' as nvarchar(100)) 
from cte 
where prev_nr <> 0 
for xml path (''), type).value('.','nvarchar(max)') 

rextester演示:http://rextester.com/QRUE46541

回報:ä‚Ú&

+0

啊哈!有效!太感謝了。從來沒有真正與XML合作過。 –

+0

@RaduGheorghiu高興地幫忙! – SqlZim

+0

@JohnCappelletti他現在在那裏! –

1

我認爲更大的問題是:你爲什麼要使用FOR XML在第一名? XML不太適合這項任務,因爲它有幾個需要編碼的「特殊」字符,因爲它們在XML中具有功能性意義。該列表很短,甚至與環境的變化(即屬性與元素/內容),如下所示:

SELECT N'& < > " ?' FOR XML PATH(''); 
-- &amp; &lt; &gt; " ? 


SELECT N'& < > " ?' AS [attr] FOR XML RAW; 
-- <row attr="&amp; &lt; &gt; &quot; ?"/> 

給你所要完成的是什麼,你會更好做實際的字符串連接如下,而不是去任何地方附近XML:

DECLARE @number INT = 651854564; 
DECLARE @Result NVARCHAR(MAX) = N''; 

;WITH cte AS (
    SELECT @number prev_nr 
     , CAST(CHAR(@number % 256) AS NVARCHAR(100)) nextchar 
    UNION ALL 
    SELECT prev_nr/256 prev_nr 
     , CAST(CHAR((prev_nr/256) % 256) AS NVARCHAR(100)) nextchar 
    FROM cte 
    WHERE prev_nr <> 0 
) 
SELECT @Result += CAST(nextchar + N'' AS NVARCHAR(100)) 
FROM cte 
WHERE prev_nr <> 0; 

SELECT @Result; 

-- ä‚Ú& 

我乾脆宣佈@Result NVARCHAR(MAX) = N'',然後改變了SELECT下手@Result +=,並取消了FOR XML

+0

其實我有一個值列表,我試圖轉換爲字符並插入到表中。儘管如此,我明白你的觀點。 +1 –

0

如果你想避免XML編碼,那麼你可以做到以下幾點:加入

SELECT STUFF((SELECT ','+Name AS [text()] FROM #Test FOR XML PATH(''), 
TYPE).value('.', 'VARCHAR(MAX)'),1,1,'') AS 'NameList' 

: ,類型).value的( '', 'VARCHAR(MAX)'),1, 1,'') 您跳過XML編碼。