FOR XML 无法序列化 char(0x0000),即使 REPLACE 函数已包含以替换 Char(0x0000)

FOR XML cannnot serialize char(0x0000) even though REPLACE function already included to replace Char(0x0000)

我正在尝试将每个 ID 的评论字段连接起来,用“;”分隔在 SQL 服务器 13 中,从多行到每个 ID 一行。同样,我使用以下查询:

--table1 在table名字中; --element_id是concatenation/aggregation需要的ID; --value 包含要连接的文本

--value的数据类型为nvarchar(max)

       ( SELECT casecomment + ';' 
           FROM (select 
    REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( 
  value
,char(0x0000),'') ,char(0x0001),'') ,char(0x0002),'') ,char(0x0003),'') ,char(0x0004),'') 
,char(0x0005),'') ,char(0x0006),'') ,char(0x0007),'') ,char(0x0008),'') ,char(0x000B),'') 
,char(0x000C),'') ,char(0x000E),'') ,char(0x000F),'') ,char(0x0010),'') ,char(0x0011),'') 
,char(0x0012),'') ,char(0x0013),'') ,char(0x0014),'') ,char(0x0015),'') ,char(0x0016),'') 
,char(0x0017),'') ,char(0x0018),'') ,char(0x0019),'') ,char(0x001A),'') ,char(0x001B),'') 
,char(0x001C),'') ,char(0x001D),'') ,char(0x001E),'') ,char(0x001F),'')
 as casecomment, element_id from table1
where element = 'comments'
) y
          WHERE x.element_id = y.element_id
          ORDER BY element_id
            FOR XML PATH('')  , TYPE).value('.','varchar(max)') as Comments     FROM (select REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( 
 value
,char(0x0000),'') ,char(0x0001),'') ,char(0x0002),'') ,char(0x0003),'') ,char(0x0004),'') 
,char(0x0005),'') ,char(0x0006),'') ,char(0x0007),'') ,char(0x0008),'') ,char(0x000B),'') 
,char(0x000C),'') ,char(0x000E),'') ,char(0x000F),'') ,char(0x0010),'') ,char(0x0011),'') 
,char(0x0012),'') ,char(0x0013),'') ,char(0x0014),'') ,char(0x0015),'') ,char(0x0016),'') 
,char(0x0017),'') ,char(0x0018),'') ,char(0x0019),'') ,char(0x001A),'') ,char(0x001B),'') 
,char(0x001C),'') ,char(0x001D),'') ,char(0x001E),'') ,char(0x001F),'') as casecomments, element_id from table1

where element = 'comments'
) x
    GROUP BY element_id```

即使我对 char(0x0000) 使用了替换,我仍然收到以下错误:

FOR XML 无法序列化节点 'NoName' 的数据,因为它包含 XML 中不允许的字符 (0x0000)。要使用 FOR XML 检索此数据,将其转换为二进制、varbinary 或图像数据类型并使用 BINARY BASE64 指令。

我的数据包含许多特殊字符(拉丁字符等),但我无法找到有问题的行。请注意,我有超过 400K 行,因此无法手动评估。 另外,我有一个旧版本的 SQL 服务器,所以翻译功能不起作用。

如有任何帮助,我们将不胜感激。谢谢。

0 字符 (0x00) 非常特殊...在最低级别上,它在许多环境中标记字符串的结尾。

试试这个

DECLARE @string VARCHAR(10)=CONCAT('a',CHAR(0),'b');

SELECT LEN(@string) AS LenString
      ,CAST(@string AS VARBINARY(10)) AS Internal
      ,@string AS cut_after_a
      ,CHARINDEX(CHAR(0),@string) AS Pos0_not_found
      ,REPLACE(@string,CHAR(0),'') AS Replace_not_working;

结果

LenString   Internal    cut_after_a Pos0_not_found  Replace_not_working
3           0x610062    a           0               a

但是您可以使用 BIN 整理来解决这个问题

SELECT LEN(@string) AS LenString
      ,CAST(@string AS VARBINARY(10)) AS Internal
      ,@string COLLATE Latin1_General_BIN AS BIN_but_cut
      ,CHARINDEX(CHAR(0) COLLATE Latin1_General_BIN,@string COLLATE Latin1_General_BIN) AS Pos0_found_at_2
      ,REPLACE(@string COLLATE Latin1_General_BIN,CHAR(0) COLLATE Latin1_General_BIN, '') AS Replace_working;

结果

LenString   Internal    BIN_but_cut Pos0_found_at_2 Replace_working
3           0x610062    a           2               ab

更新:FOR XML 适合我...

尝试使用 PATH(大多数情况下推荐的方法):

DECLARE @string VARCHAR(10)=CONCAT('a',CHAR(0),'b');

SELECT @string FOR XML PATH('test');

结果

<test>a&#x0;b</test>

你可能 .