我有一个查询,它将一个数字转换为一组ASCII字符,然后尝试将它们连接成一个字符串:
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
连接起来时,它们会更改编码,以便最终将&
转换并连接到最终结果中:ä‚Ú&
如何解决此问题,以便我可以获得正确的编码并生成ä‚Ú&
结果?
我已经尝试将所有内容转换为nvarchar(100)
,但我觉得这没有任何影响(实际上几乎与编码无关 - 或者至少在我的方案中无用)。
我还尝试过知名的STUFF
和FOR XML
,但这并没有真正帮助。
答案 0 :(得分: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
返回:ä‚Ú&
答案 1 :(得分:1)
我认为更大的问题是:你为什么首先使用FOR XML
? XML不适合这项任务,因为它有几个需要编码的“特殊”字符,因为它们在XML中具有功能意义。列表很短,甚至可以根据上下文(即属性与元素/内容)进行更改,如下所示:
SELECT N'& < > " ?' FOR XML PATH('');
-- & < > " ?
SELECT N'& < > " ?' AS [attr] FOR XML RAW;
-- <row attr="& < > " ?"/>
考虑到你要完成的任务,你最好按照以下方式进行实际的字符串连接,而不是靠近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
。
答案 2 :(得分:0)
如果您想避免使用XML编码,那么您可以执行以下操作:
SELECT STUFF((SELECT ','+Name AS [text()] FROM #Test FOR XML PATH(''),
TYPE).value('.', 'VARCHAR(MAX)'),1,1,'') AS 'NameList'
添加: ,类型).value(&#39;。&#39;,&#39; VARCHAR(MAX)&#39;),1,1,&#39;&#39;) 你跳过XML编码。