【问题标题】:Store UTF8 data in UTF16 column将 UTF8 数据存储在 UTF16 列中
【发布时间】:2012-06-08 10:17:28
【问题描述】:

我将 XML 存储在 SQL Server 的 XML 列中。 SQL Server 在内部以 UTF-16 存储数据。因此,存储的 XML 必须采用 UTF-16 格式。

我的 XML 是 utf-8 格式,上面有这个声明:

<?xml version="1.0" encoding="UTF-8" ?>

当我尝试使用 UTF-8 声明插入 xml 时,我收到一个异常,说明有关编码的内容。我可以通过两种方式轻松解决此问题:

  • 通过删除声明或

  • 通过将声明更改为

<?xml version="1.0" encoding="UTF-16" ?>

问题

我不知道删除或替换声明是否“安全”或正确。我会丢失数据,还是 XML 会损坏?还是我必须将 C# 中的字符串从 utf-8 转换为 utf-16?

【问题讨论】:

  • 引用您遇到但目前不理解的任何异常总是一个好主意。
  • 如果您将文件存储为文本,则将它们存储为文本(即也将它们视为文本,这意味着应用通用编码)。当然,这需要您删除内联编码声明。我只是将它们存储为 blob,但这消除了这些考虑。
  • SQL Server 在内部将数据存储为 UCS-2,而不是 UTF-16。这仅在您使用 UTF-16 代理对时才真正重要。
  • xml 有多大?如果它很小,您可以在 C# 中轻松加载它并保存到 StringWriter,它将使用 UTF-16
  • @Ed Harper:也许您可以解释一下如果您在 C# 中读取代理对并将其传输到 SQL Server 会发生什么?特别是如果您将encoding="UTF-16" 放在必须是 UCS-2 的 C# 字符串上。

标签: c# sql-server xml


【解决方案1】:

C# 将字符串存储在 UCS-2 中,这是 UTF-16 标准的旧版本。因此,当您在 C# 中读取 UTF-8 字符串时,C# 会将其转换为 UCS-2。它是您传输到 SQL Server 的 UCS-2 变体。

您可以将 xml 声明更改为 encoding="UTF-16" 或完全省略它。 UCS-2 和 UTF-16 有一些区别;我很想知道这会如何影响 C# 和 SQL Server!

【讨论】:

  • 这些差异几乎没有实际影响。 UCS-2 只能表示 21 位 Unicode(称为 BMP)的 16 位部分。但是,如果数据中出现非 BMP 字符(这在大多数语言中非常罕见),则它们分别用两个“代理”表示并且无论如何都可以通过。您可能会得到不准确的 DATALENGTH 值,但您可能永远不会注意到。
  • @JirkaHanika:所以虽然 UTF-16 添加了一种额外的方式来表示非 BMP 字符,但它并没有使旧方式失效?
  • 它没有。但 SQL Server 将继续将其视为固定宽度编码,将非 BMP 字符视为两个“字符”。例如,如果您有一个 nvarchar(1) 列,那么您根本无法将非 BMP 字符放入其中。
  • @JirkaHanika:那么在 XML 声明中将非 BMP 字符作为代理对与encoding="utf-16" 一起传输是否有效?
  • 当然。我不知道驱动程序是否在某些版本中也不能转换其他编码,但 UTF16 和 UCS2 是一回事,只要您不必解释内容(例如,计数字符)。
【解决方案2】:

SQL Server 内部使用 UCS-2 存储 XML 数据,但这与您将数据传递给 SQL Server 的形式无关。

例如,如果您使用 varchar 文字插入它,请将其改为 nvarchar 文字并将编码声明为 UTF-16。示例:

DECLARE @VAR XML
INSERT INTO MyTable (MyXmlColumn) 
    VALUES (N'<?xml version="1.0" encoding="UTF-16" ?><doc></doc>')

【讨论】:

  • OP 提到了一个 C# 客户端,所以他可能没有使用 SQL 文字
猜你喜欢
  • 1970-01-01
  • 2013-05-29
  • 2014-09-11
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 2014-11-29
相关资源
最近更新 更多