最重要的问题是:为什么需要声明?
重要提示:此声明不是 XML 的必要部分,而是提示消费者如何阅读内容。
在大多数情况下,这个声明告诉消费者一个文本文件的编码。那里有数以百万计的 XML 文件大喊 encoding="utf8" 或类似的东西,但 - 事实上 - 该文件是 utf16,纯 ASCII 或任何其他编码。如果声明没有说真话,最好不要有这样的声明……
在 SQL-Server 中,有三种存储 XML 的选项(这里不讨论 binary 或过时的 text):最好是 native XML,它在底层使用基于 nvarchar 的层次结构表,以及(一个糟糕的选择,但是)经常看到的是基于两种字符串类型之一的基于字符串的列。您必须知道,SQL-Server 可以处理(var)char(x)(即排序规则扩展的ASCII),以及n(var)char(x),即UCS-2(几乎与utf16 相同)。
在这种情况下存储带有声明的 XML 有什么好处? SQL-Server 可以直接从用于存储的类型中获取编码。在字符串级别上,您可以存储任何内容,甚至是无效/格式不正确的 XML。但是,在您输入 native XML 类型的那一刻,SQL-Server 将忽略任何声明并拒绝违反规则的 XML。
回答你的问题
如果确实需要,添加声明的唯一机会是将 XML 转换为字符串类型并在字符串级别添加声明。
请记住
- 您不能在不丢失声明的情况下将其带回原生 XML。
- 如果您声明任何编码,您应该确保写入的目标文件不是骗子。
几年前我也有同样的问题(需要添加样式表提示)。
你可能会读到这个related question (and a good answer by har07)。我自己的回答具体反映了<?xml blahblah ?>。
最后的提示
开始 with v2019 there is native utf-8 support with some special collations 和 starting with v2014SP2 there was UTF-8 support for BCP。
您可以使用此代码查找排序规则的编码:
select [name]
,[description]
,COLLATIONPROPERTY([name],'codepage') [codepage]
from sys.fn_helpcollations();
然后 - 在此之后 - 你可能会使用类似这样的东西
<?xml version="1.0" encoding="windows-1252"?>
正确反映所选编码。
一般提示:使用字符串类型 NVARCHAR(MAX) 和 utf-16 在(几乎)任何情况下都有效。