以XML数据类型存储特殊字符(例如&)

5 xml sql sql-server sql-server-2008

如果我做

Declare @t table(Email xml)
Declare @email varchar(100) = 'xxx&xx@monop.com'
Insert into @t  
select '<Emails> <Email>' + @email +'</Email></Emails>'
select * From @t
Run Code Online (Sandbox Code Playgroud)

我会得到预期的错误

消息9411,级别16,状态1,行8 XML解析:第1行,第27个字符,预期分号

我几乎在任何地方(包括SO)找到的一个解决方案就是replace '&' with '&amp;并且它有效

Insert into @t  
select CAST('<Emails><Email>' + REPLACE(@email, '&', '&amp;') + '</Email></Emails>' AS XML)
Run Code Online (Sandbox Code Playgroud)

产量

<Emails><Email>xxx&amp;xx@monop.com</Email></Emails>
Run Code Online (Sandbox Code Playgroud)

但是,我尝试使用CData方法(只是解决问题的另一种方法)

Declare @t table(Email xml)
Declare @email varchar(100) = 'xxx&xx@monop.com'
Insert into @t  
Select CAST('<![CDATA[Emails> <Email>' + @email + '</Email> </Emails]]>' AS XML)
select * From @t
Run Code Online (Sandbox Code Playgroud)

当我得到以下输出

Emails&gt; &lt;Email&gt;xxx&amp;xx@monop.com&lt;/Email&gt; &lt;/Emails
Run Code Online (Sandbox Code Playgroud)

我想要实现的是按原样存储数据,即所需的输出应该是

<Emails><Email>xxx&xx@monop.com</Email></Emails>
Run Code Online (Sandbox Code Playgroud)

它可能吗?

我知道如果xml无法理解的任何其他特殊字符将作为输入传递给它,则替换函数将失败,例如'<'我再次需要替换它...

谢谢

Ign*_*ams 3

标签是PCDATA,而不是CDATA,所以不要将它们放在CDATA 部分。

  • 这就像问为什么我们不能使用句号来结束每个单词一样。因为它被用来做其他事情。这就是我们对其进行编码的原因。 (2认同)